gtkmountoperation.h \
gtknotebook.h \
gtkoffscreenwindow.h \
- gtkopenwith.h \
- gtkopenwithdialog.h \
- gtkopenwithwidget.h \
- gtkopenwithonline.h \
+ gtkappchooser.h \
+ gtkappchooserdialog.h \
+ gtkappchooserwidget.h \
+ gtkappchooseronline.h \
gtkorientable.h \
gtkpagesetup.h \
gtkpaned.h \
gtktextlayout.h
if ENABLE_PACKAGEKIT
-gtk_openwith_impl_h_sources = \
- gtkopenwithonlinepk.h \
+gtk_appchooser_impl_h_sources = \
+ gtkappchooseronlinepk.h \
$(NULL)
endif
if ENABLE_PACKAGEKIT
-gtk_openwith_impl_c_sources = \
- gtkopenwithonlinepk.c \
+gtk_appchooser_impl_c_sources = \
+ gtkappchooseronlinepk.c \
$(NULL)
endif
gtkmenuprivate.h \
gtkmnemonichash.h \
gtkmountoperationprivate.h \
- gtkopenwithprivate.h \
- gtkopenwithmodule.h \
- gtkopenwithonlinedummy.h \
+ gtkappchooserprivate.h \
+ gtkappchoosermodule.h \
+ gtkappchooseronlinedummy.h \
gtkpango.h \
gtkpathbar.h \
gtkplugprivate.h \
gtkwindow-decorate.h \
gtkwidgetprivate.h \
$(gtk_clipboard_dnd_h_sources) \
- $(gtk_openwith_impl_h_sources)
+ $(gtk_appchooser_impl_h_sources)
# GTK+ C sources to build the library from
gtk_base_c_sources = \
gtkmountoperation.c \
gtknotebook.c \
gtkoffscreenwindow.c \
- gtkopenwith.c \
- gtkopenwithwidget.c \
- gtkopenwithdialog.c \
- gtkopenwithmodule.c \
- gtkopenwithonline.c \
- gtkopenwithonlinedummy.c \
+ gtkappchooser.c \
+ gtkappchooserwidget.c \
+ gtkappchooserdialog.c \
+ gtkappchoosermodule.c \
+ gtkappchooseronline.c \
+ gtkappchooseronlinedummy.c \
gtkorientable.c \
gtkpagesetup.c \
gtkpaned.c \
gtkwindow-decorate.c \
gtkwindow.c \
$(gtk_clipboard_dnd_c_sources) \
- $(gtk_openwith_impl_c_sources)
+ $(gtk_appchooser_impl_c_sources)
gtk_c_sources = $(gtk_base_c_sources)
gtk_all_c_sources = $(gtk_base_c_sources)
#include <gtk/gtkmountoperation.h>
#include <gtk/gtknotebook.h>
#include <gtk/gtkoffscreenwindow.h>
-#include <gtk/gtkopenwith.h>
-#include <gtk/gtkopenwithdialog.h>
-#include <gtk/gtkopenwithwidget.h>
+#include <gtk/gtkappchooser.h>
+#include <gtk/gtkappchooserdialog.h>
+#include <gtk/gtkappchooserwidget.h>
#include <gtk/gtkorientable.h>
#include <gtk/gtkpagesetup.h>
#include <gtk/gtkpapersize.h>
--- /dev/null
+/*
+ * gtkappchooser.c: app-chooser interface
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#include <config.h>
+
+#include "gtkappchooser.h"
+
+#include "gtkintl.h"
+#include "gtkappchooserprivate.h"
+#include "gtkwidget.h"
+
+#include <glib.h>
+
+G_DEFINE_INTERFACE (GtkAppChooser, gtk_app_chooser, GTK_TYPE_WIDGET);
+
+static void
+gtk_app_chooser_default_init (GtkAppChooserIface *iface)
+{
+ GParamSpec *pspec;
+
+ pspec = g_param_spec_string ("content-type",
+ P_("Content type"),
+ P_("The content type used by the open with object"),
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_interface_install_property (iface, pspec);
+}
+
+gchar *
+gtk_app_chooser_get_content_type (GtkAppChooser *self)
+{
+ gchar *retval = NULL;
+
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER (self), NULL);
+
+ g_object_get (self,
+ "content-type", &retval,
+ NULL);
+
+ return retval;
+}
+
+GAppInfo *
+gtk_app_chooser_get_app_info (GtkAppChooser *self)
+{
+ return GTK_APP_CHOOSER_GET_IFACE (self)->get_app_info (self);
+}
+
+void
+gtk_app_chooser_refresh (GtkAppChooser *self)
+{
+ GTK_APP_CHOOSER_GET_IFACE (self)->refresh (self);
+}
--- /dev/null
+/*
+ * gtkappchooser.h: app-chooser interface
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_APP_CHOOSER_H__
+#define __GTK_APP_CHOOSER_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_APP_CHOOSER\
+ (gtk_app_chooser_get_type ())
+#define GTK_APP_CHOOSER(obj)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_APP_CHOOSER, GtkAppChooser))
+#define GTK_IS_APP_CHOOSER(obj)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_APP_CHOOSER))
+
+typedef struct _GtkAppChooser GtkAppChooser;
+
+GType gtk_app_chooser_get_type () G_GNUC_CONST;
+
+GAppInfo * gtk_app_chooser_get_app_info (GtkAppChooser *self);
+gchar * gtk_app_chooser_get_content_type (GtkAppChooser *self);
+void gtk_app_chooser_refresh (GtkAppChooser *self);
+
+G_END_DECLS
+
+#endif /* __GTK_APP_CHOOSER_H__ */
+
--- /dev/null
+/*
+ * gtkappchooserdialog.c: an app-chooser dialog
+ *
+ * Copyright (C) 2004 Novell, Inc.
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Dave Camp <dave@novell.com>
+ * Alexander Larsson <alexl@redhat.com>
+ * Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#include <config.h>
+
+#include "gtkappchooserdialog.h"
+
+#include "gtkintl.h"
+#include "gtkappchooser.h"
+#include "gtkappchooseronline.h"
+#include "gtkappchooserprivate.h"
+
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+#define sure_string(s) ((const char *) ((s) != NULL ? (s) : ""))
+
+struct _GtkAppChooserDialogPrivate {
+ char *content_type;
+ GFile *gfile;
+
+ GtkWidget *label;
+ GtkWidget *button;
+ GtkWidget *online_button;
+
+ GtkWidget *open_label;
+
+ GtkWidget *app_chooser_widget;
+ GtkWidget *show_more_button;
+
+ gboolean show_more_clicked;
+};
+
+enum {
+ PROP_GFILE = 1,
+ PROP_CONTENT_TYPE,
+ N_PROPERTIES
+};
+
+static void gtk_app_chooser_dialog_iface_init (GtkAppChooserIface *iface);
+G_DEFINE_TYPE_WITH_CODE (GtkAppChooserDialog, gtk_app_chooser_dialog, GTK_TYPE_DIALOG,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER,
+ gtk_app_chooser_dialog_iface_init));
+
+static void
+show_error_dialog (const gchar *primary,
+ const gchar *secondary,
+ GtkWindow *parent)
+{
+ GtkWidget *message_dialog;
+
+ message_dialog = gtk_message_dialog_new (parent, 0,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ NULL);
+ g_object_set (message_dialog,
+ "text", primary,
+ "secondary-text", secondary,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (message_dialog), GTK_RESPONSE_OK);
+
+ gtk_widget_show (message_dialog);
+
+ g_signal_connect (message_dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+}
+
+static void
+search_for_mimetype_ready_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkAppChooserOnline *online = GTK_APP_CHOOSER_ONLINE (source);
+ GtkAppChooserDialog *self = user_data;
+ GError *error = NULL;
+
+ gtk_app_chooser_online_search_for_mimetype_finish (online, res, &error);
+
+ if (error != NULL)
+ {
+ show_error_dialog (_("Failed to look for applications online"),
+ error->message, GTK_WINDOW (self));
+ g_error_free (error);
+ }
+ else
+ {
+ gtk_app_chooser_refresh (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
+ }
+
+ g_object_unref (online);
+}
+
+static void
+online_button_clicked_cb (GtkButton *b,
+ gpointer user_data)
+{
+ GtkAppChooserOnline *online;
+ GtkAppChooserDialog *self = user_data;
+
+ online = gtk_app_chooser_online_get_default ();
+
+ gtk_app_chooser_online_search_for_mimetype_async (online,
+ self->priv->content_type,
+ GTK_WINDOW (self),
+ search_for_mimetype_ready_cb,
+ self);
+}
+
+/* An application is valid if:
+ *
+ * 1) The file exists
+ * 2) The user has permissions to run the file
+ */
+static gboolean
+check_application (GtkAppChooserDialog *self,
+ GAppInfo **app_out)
+{
+ const char *command;
+ char *path = NULL;
+ char **argv = NULL;
+ int argc;
+ GError *error = NULL;
+ gint retval = TRUE;
+ GAppInfo *info;
+
+ command = NULL;
+
+ info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
+ command = g_app_info_get_executable (info);
+
+ g_shell_parse_argv (command, &argc, &argv, &error);
+
+ if (error)
+ {
+ show_error_dialog (_("Could not run application"),
+ error->message,
+ GTK_WINDOW (self));
+ g_error_free (error);
+ retval = FALSE;
+ goto cleanup;
+ }
+
+ path = g_find_program_in_path (argv[0]);
+ if (!path)
+ {
+ char *error_message;
+
+ error_message = g_strdup_printf (_("Could not find '%s'"),
+ argv[0]);
+
+ show_error_dialog (_("Could not find application"),
+ error_message,
+ GTK_WINDOW (self));
+ g_free (error_message);
+ retval = FALSE;
+ goto cleanup;
+ }
+
+ *app_out = info;
+
+ cleanup:
+ g_strfreev (argv);
+ g_free (path);
+
+ return retval;
+}
+
+static void
+widget_application_selected_cb (GtkAppChooserWidget *widget,
+ GAppInfo *app_info,
+ gpointer user_data)
+{
+ GtkAppChooserDialog *self = user_data;
+
+ gtk_widget_set_sensitive (self->priv->button, TRUE);
+}
+
+static void
+widget_application_activated_cb (GtkAppChooserWidget *widget,
+ GAppInfo *app_info,
+ gpointer user_data)
+{
+ GtkAppChooserDialog *self = user_data;
+
+ gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
+}
+
+static char *
+get_extension (const char *basename)
+{
+ char *p;
+
+ p = strrchr (basename, '.');
+
+ if (p && *(p + 1) != '\0')
+ return g_strdup (p + 1);
+
+ return NULL;
+}
+
+static void
+set_dialog_properties (GtkAppChooserDialog *self)
+{
+ char *label, *name, *extension, *description, *default_text, *string;
+ PangoFontDescription *font_desc;
+
+ name = NULL;
+ extension = NULL;
+ label = NULL;
+ description = NULL;
+
+ if (self->priv->gfile != NULL)
+ {
+ name = g_file_get_basename (self->priv->gfile);
+ extension = get_extension (name);
+ }
+
+ description = g_content_type_get_description (self->priv->content_type);
+ gtk_window_set_title (GTK_WINDOW (self), "");
+
+ if (name != NULL)
+ {
+ /* Translators: %s is a filename */
+ label = g_strdup_printf (_("Select an application to open \"%s\""), name);
+ string = g_strdup_printf (_("No applications available to open \"%s\""),
+ name);
+ }
+ else
+ {
+ /* Translators: %s is a file type description */
+ label = g_strdup_printf (_("Select an application for \"%s\" files"),
+ g_content_type_is_unknown (self->priv->content_type) ?
+ self->priv->content_type : description);
+ string = g_strdup_printf (_("No applications available to open \"%s\" files"),
+ g_content_type_is_unknown (self->priv->content_type) ?
+ self->priv->content_type : description);
+ }
+
+ font_desc = pango_font_description_new ();
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+ gtk_widget_modify_font (self->priv->label, font_desc);
+ pango_font_description_free (font_desc);
+
+ gtk_label_set_markup (GTK_LABEL (self->priv->label), label);
+
+ default_text = g_strdup_printf ("<big><b>%s</b></big>\n%s",
+ string,
+ _("Click \"Show other applications\", for more options, or "
+ "\"Find applications online\" to install a new application"));
+
+ gtk_app_chooser_widget_set_default_text (GTK_APP_CHOOSER_WIDGET (self->priv->app_chooser_widget),
+ default_text);
+
+ g_free (label);
+ g_free (name);
+ g_free (extension);
+ g_free (description);
+ g_free (string);
+ g_free (default_text);
+}
+
+static void
+show_more_button_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ GtkAppChooserDialog *self = user_data;
+
+ g_object_set (self->priv->app_chooser_widget,
+ "show-recommended", TRUE,
+ "show-fallback", TRUE,
+ "show-other", TRUE,
+ NULL);
+
+ gtk_widget_hide (self->priv->show_more_button);
+ self->priv->show_more_clicked = TRUE;
+}
+
+static void
+widget_notify_for_button_cb (GObject *source,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GtkAppChooserDialog *self = user_data;
+ GtkAppChooserWidget *widget = GTK_APP_CHOOSER_WIDGET (source);
+ gboolean should_hide;
+
+ should_hide = gtk_app_chooser_widget_get_show_all (widget) ||
+ self->priv->show_more_clicked;
+
+ if (should_hide)
+ gtk_widget_hide (self->priv->show_more_button);
+}
+
+static void
+build_dialog_ui (GtkAppChooserDialog *self)
+{
+ GtkWidget *vbox;
+ GtkWidget *vbox2;
+ GtkWidget *label;
+ GtkWidget *action_area, *button, *w;
+
+ gtk_container_set_border_width (GTK_CONTAINER (self), 5);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), vbox, TRUE, TRUE, 0);
+ gtk_widget_show (vbox);
+
+ vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
+ gtk_widget_show (vbox2);
+
+ self->priv->label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (self->priv->label), 0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (self->priv->label), TRUE);
+ gtk_box_pack_start (GTK_BOX (vbox2), self->priv->label,
+ FALSE, FALSE, 0);
+ gtk_widget_show (self->priv->label);
+
+ self->priv->app_chooser_widget =
+ gtk_app_chooser_widget_new (self->priv->content_type);
+ gtk_box_pack_start (GTK_BOX (vbox2), self->priv->app_chooser_widget, TRUE, TRUE, 0);
+ gtk_widget_show (self->priv->app_chooser_widget);
+
+ g_signal_connect (self->priv->app_chooser_widget, "application-selected",
+ G_CALLBACK (widget_application_selected_cb), self);
+ g_signal_connect (self->priv->app_chooser_widget, "application-activated",
+ G_CALLBACK (widget_application_activated_cb), self);
+ g_signal_connect (self->priv->app_chooser_widget, "notify::show-all",
+ G_CALLBACK (widget_notify_for_button_cb), self);
+
+ button = gtk_button_new_with_label (_("Show other applications"));
+ self->priv->show_more_button = button;
+ w = gtk_image_new_from_stock (GTK_STOCK_ADD,
+ GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (button), w);
+ gtk_box_pack_start (GTK_BOX (self->priv->app_chooser_widget), button, FALSE, FALSE, 6);
+ gtk_widget_show_all (button);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (show_more_button_clicked_cb), self);
+
+ gtk_dialog_add_button (GTK_DIALOG (self),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+
+ /* Create a custom stock icon */
+ self->priv->button = gtk_button_new ();
+
+ label = gtk_label_new_with_mnemonic (_("_Open"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (self->priv->button));
+ gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
+ gtk_widget_show (label);
+ self->priv->open_label = label;
+
+ gtk_container_add (GTK_CONTAINER (self->priv->button),
+ self->priv->open_label);
+
+ gtk_widget_show (self->priv->button);
+ gtk_widget_set_can_default (self->priv->button, TRUE);
+
+ gtk_dialog_add_action_widget (GTK_DIALOG (self),
+ self->priv->button, GTK_RESPONSE_OK);
+
+ action_area = gtk_dialog_get_action_area (GTK_DIALOG (self));
+ self->priv->online_button = gtk_button_new_with_label (_("Find applications online"));
+ gtk_box_pack_start (GTK_BOX (action_area), self->priv->online_button,
+ FALSE, FALSE, 0);
+ gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), self->priv->online_button,
+ TRUE);
+ gtk_widget_show (self->priv->online_button);
+ g_signal_connect (self->priv->online_button, "clicked",
+ G_CALLBACK (online_button_clicked_cb), self);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (self),
+ GTK_RESPONSE_OK);
+}
+
+static void
+set_gfile_and_content_type (GtkAppChooserDialog *self,
+ GFile *file)
+{
+ GFileInfo *info;
+
+ if (file == NULL)
+ return;
+
+ self->priv->gfile = g_object_ref (file);
+
+ info = g_file_query_info (self->priv->gfile,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ 0, NULL, NULL);
+ self->priv->content_type = g_strdup (g_file_info_get_content_type (info));
+
+ g_object_unref (info);
+}
+
+static GAppInfo *
+gtk_app_chooser_dialog_get_app_info (GtkAppChooser *object)
+{
+ GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
+ GAppInfo *app = NULL;
+
+ if (!check_application (self, &app))
+ return NULL;
+
+ return app;
+}
+
+static void
+gtk_app_chooser_dialog_refresh (GtkAppChooser *object)
+{
+ GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
+
+ gtk_app_chooser_refresh (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
+}
+
+static void
+gtk_app_chooser_dialog_constructed (GObject *object)
+{
+ GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
+
+ g_assert (self->priv->content_type != NULL ||
+ self->priv->gfile != NULL);
+
+ if (G_OBJECT_CLASS (gtk_app_chooser_dialog_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (gtk_app_chooser_dialog_parent_class)->constructed (object);
+
+ build_dialog_ui (self);
+ set_dialog_properties (self);
+}
+
+static void
+gtk_app_chooser_dialog_finalize (GObject *object)
+{
+ GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
+
+ if (self->priv->gfile)
+ g_object_unref (self->priv->gfile);
+
+ g_free (self->priv->content_type);
+
+ G_OBJECT_CLASS (gtk_app_chooser_dialog_parent_class)->finalize (object);
+}
+
+static void
+gtk_app_chooser_dialog_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
+
+ switch (property_id)
+ {
+ case PROP_GFILE:
+ set_gfile_and_content_type (self, g_value_get_object (value));
+ break;
+ case PROP_CONTENT_TYPE:
+ /* don't try to override a value previously set with the GFile */
+ if (self->priv->content_type == NULL)
+ self->priv->content_type = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_app_chooser_dialog_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
+
+ switch (property_id)
+ {
+ case PROP_GFILE:
+ if (self->priv->gfile != NULL)
+ g_value_set_object (value, self->priv->gfile);
+ break;
+ case PROP_CONTENT_TYPE:
+ g_value_set_string (value, self->priv->content_type);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_app_chooser_dialog_iface_init (GtkAppChooserIface *iface)
+{
+ iface->get_app_info = gtk_app_chooser_dialog_get_app_info;
+ iface->refresh = gtk_app_chooser_dialog_refresh;
+}
+
+static void
+gtk_app_chooser_dialog_class_init (GtkAppChooserDialogClass *klass)
+{
+ GObjectClass *gobject_class;
+ GParamSpec *pspec;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = gtk_app_chooser_dialog_finalize;
+ gobject_class->set_property = gtk_app_chooser_dialog_set_property;
+ gobject_class->get_property = gtk_app_chooser_dialog_get_property;
+ gobject_class->constructed = gtk_app_chooser_dialog_constructed;
+
+ g_object_class_override_property (gobject_class, PROP_CONTENT_TYPE, "content-type");
+
+ pspec = g_param_spec_object ("gfile",
+ P_("GFile"),
+ P_("The GFile used by the open with dialog"),
+ G_TYPE_FILE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_GFILE, pspec);
+
+ g_type_class_add_private (klass, sizeof (GtkAppChooserDialogPrivate));
+}
+
+static void
+gtk_app_chooser_dialog_init (GtkAppChooserDialog *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_APP_CHOOSER_DIALOG,
+ GtkAppChooserDialogPrivate);
+}
+
+static void
+set_parent_and_flags (GtkWidget *dialog,
+ GtkWindow *parent,
+ GtkDialogFlags flags)
+{
+ if (parent != NULL)
+ gtk_window_set_transient_for (GTK_WINDOW (dialog),
+ parent);
+
+ if (flags & GTK_DIALOG_MODAL)
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ if (flags & GTK_DIALOG_DESTROY_WITH_PARENT)
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+}
+
+/**
+ * gtk_app_chooser_dialog_new:
+ * @parent: (allow-none): a #GtkWindow, or %NULL
+ * @flags: flags for this dialog
+ * @file: a #GFile
+ *
+ * Creates a new #GtkAppChooserDialog for the provided #GFile, to allow
+ * the user to select an application for it.
+ *
+ * Returns: a newly created #GtkAppChooserDialog
+ *
+ * Since: 3.0
+ **/
+GtkWidget *
+gtk_app_chooser_dialog_new (GtkWindow *parent,
+ GtkDialogFlags flags,
+ GFile *file)
+{
+ GtkWidget *retval;
+
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+
+ retval = g_object_new (GTK_TYPE_APP_CHOOSER_DIALOG,
+ "gfile", file,
+ NULL);
+
+ set_parent_and_flags (retval, parent, flags);
+
+ return retval;
+}
+
+/**
+ * gtk_app_chooser_dialog_new_for_content_type:
+ * @parent: (allow-none): a #GtkWindow, or %NULL
+ * @flags: flags for this dialog
+ * @content_type: a content type string
+ *
+ * Creates a new #GtkAppChooserDialog for the provided content type, to allow
+ * the user to select an application for it.
+ *
+ * Returns: a newly created #GtkAppChooserDialog
+ *
+ * Since: 3.0
+ **/
+GtkWidget *
+gtk_app_chooser_dialog_new_for_content_type (GtkWindow *parent,
+ GtkDialogFlags flags,
+ const gchar *content_type)
+{
+ GtkWidget *retval;
+
+ g_return_val_if_fail (content_type != NULL, NULL);
+
+ retval = g_object_new (GTK_TYPE_APP_CHOOSER_DIALOG,
+ "content-type", content_type,
+ NULL);
+
+ set_parent_and_flags (retval, parent, flags);
+
+ return retval;
+}
+
+GtkWidget *
+gtk_app_chooser_dialog_get_widget (GtkAppChooserDialog *self)
+{
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER_DIALOG (self), NULL);
+
+ return self->priv->app_chooser_widget;
+}
--- /dev/null
+/*
+ * gtkappchooserdialog.h: an app-chooser dialog
+ *
+ * Copyright (C) 2004 Novell, Inc.
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Dave Camp <dave@novell.com>
+ * Alexander Larsson <alexl@redhat.com>
+ * Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_APP_CHOOSER_DIALOG_H__
+#define __GTK_APP_CHOOSER_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+#include <gio/gio.h>
+
+#define GTK_TYPE_APP_CHOOSER_DIALOG\
+ (gtk_app_chooser_dialog_get_type ())
+#define GTK_APP_CHOOSER_DIALOG(obj)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_APP_CHOOSER_DIALOG, GtkAppChooserDialog))
+#define GTK_APP_CHOOSER_DIALOG_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_APP_CHOOSER_DIALOG, GtkAppChooserDialogClass))
+#define GTK_IS_APP_CHOOSER_DIALOG(obj)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_APP_CHOOSER_DIALOG))
+#define GTK_IS_APP_CHOOSER_DIALOG_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_APP_CHOOSER_DIALOG))
+#define GTK_APP_CHOOSER_DIALOG_GET_CLASS(obj)\
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_APP_CHOOSER_DIALOG, GtkAppChooserDialogClass))
+
+typedef struct _GtkAppChooserDialog GtkAppChooserDialog;
+typedef struct _GtkAppChooserDialogClass GtkAppChooserDialogClass;
+typedef struct _GtkAppChooserDialogPrivate GtkAppChooserDialogPrivate;
+
+struct _GtkAppChooserDialog {
+ GtkDialog parent;
+
+ /*< private >*/
+ GtkAppChooserDialogPrivate *priv;
+};
+
+struct _GtkAppChooserDialogClass {
+ GtkDialogClass parent_class;
+
+ /* padding for future class expansion */
+ gpointer padding[16];
+};
+
+GType gtk_app_chooser_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gtk_app_chooser_dialog_new (GtkWindow *parent,
+ GtkDialogFlags flags,
+ GFile *file);
+GtkWidget * gtk_app_chooser_dialog_new_for_content_type (GtkWindow *parent,
+ GtkDialogFlags flags,
+ const gchar *content_type);
+
+GtkWidget * gtk_app_chooser_dialog_get_widget (GtkAppChooserDialog *self);
+
+#endif /* __GTK_APP_CHOOSER_DIALOG_H__ */
--- /dev/null
+/*
+ * gtkappchoosermodule.c: an extension point for online integration
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#include <config.h>
+
+#include "gtkappchoosermodule.h"
+
+#include <gio/gio.h>
+
+#include "gtkappchooseronline.h"
+#include "gtkappchooseronlinedummy.h"
+
+#ifdef ENABLE_PACKAGEKIT
+#include "gtkappchooseronlinepk.h"
+#endif
+
+G_LOCK_DEFINE_STATIC (registered_ep);
+
+void
+_gtk_app_chooser_module_ensure (void)
+{
+ static gboolean registered_ep = FALSE;
+ GIOExtensionPoint *ep;
+
+ G_LOCK (registered_ep);
+
+ if (!registered_ep)
+ {
+ registered_ep = TRUE;
+
+ ep = g_io_extension_point_register ("gtkappchooser-online");
+ g_io_extension_point_set_required_type (ep, GTK_TYPE_APP_CHOOSER_ONLINE);
+
+ _gtk_app_chooser_online_dummy_get_type ();
+
+#ifdef ENABLE_PACKAGEKIT
+ _gtk_app_chooser_online_pk_get_type ();
+#endif
+ }
+
+ G_UNLOCK (registered_ep);
+}
--- /dev/null
+/*
+ * gtkappchoosermodule.h: an extension point for online integration
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#ifndef __GTK_APP_CHOOSER_MODULE_H__
+#define __GTK_APP_CHOOSER_MODULE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void _gtk_app_chooser_module_ensure (void);
+
+G_END_DECLS
+
+#endif /* __GTK_APP_CHOOSER_MODULE_H__ */
--- /dev/null
+/*
+ * gtkappchooseronline.h: an extension point for online integration
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#include <config.h>
+
+#include "gtkappchooseronline.h"
+
+#include "gtkappchooseronlinedummy.h"
+#include "gtkappchoosermodule.h"
+
+#include <gio/gio.h>
+
+G_DEFINE_INTERFACE (GtkAppChooserOnline, gtk_app_chooser_online, G_TYPE_OBJECT);
+
+static void
+gtk_app_chooser_online_default_init (GtkAppChooserOnlineInterface *iface)
+{
+ /* do nothing */
+}
+
+GtkAppChooserOnline *
+gtk_app_chooser_online_get_default (void)
+{
+ GIOExtensionPoint *ep;
+ GIOExtension *extension;
+ GList *extensions;
+ GtkAppChooserOnline *retval;
+
+ _gtk_app_chooser_module_ensure ();
+
+ ep = g_io_extension_point_lookup ("gtkappchooser-online");
+ extensions = g_io_extension_point_get_extensions (ep);
+
+ if (extensions != NULL)
+ {
+ /* pick the first */
+ extension = extensions->data;
+ retval = g_object_new (g_io_extension_get_type (extension),
+ NULL);
+ }
+ else
+ {
+ retval = g_object_new (GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY,
+ NULL);
+ }
+
+ return retval;
+}
+
+void
+gtk_app_chooser_online_search_for_mimetype_async (GtkAppChooserOnline *self,
+ const gchar *content_type,
+ GtkWindow *parent,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GtkAppChooserOnlineInterface *iface;
+
+ g_return_if_fail (GTK_IS_APP_CHOOSER_ONLINE (self));
+
+ iface = GTK_APP_CHOOSER_ONLINE_GET_IFACE (self);
+
+ (* iface->search_for_mimetype_async) (self, content_type, parent, callback, user_data);
+}
+
+gboolean
+gtk_app_chooser_online_search_for_mimetype_finish (GtkAppChooserOnline *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ GtkAppChooserOnlineInterface *iface;
+
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER_ONLINE (self), FALSE);
+
+ iface = GTK_APP_CHOOSER_ONLINE_GET_IFACE (self);
+
+ return ((* iface->search_for_mimetype_finish) (self, res, error));
+}
--- /dev/null
+/*
+ * gtkappchooseronline.h: an extension point for online integration
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#ifndef __GTK_APP_CHOOSER_ONLINE_H__
+#define __GTK_APP_CHOOSER_ONLINE_H__
+
+#include <glib.h>
+
+#include <gtk/gtkwindow.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_APP_CHOOSER_ONLINE\
+ (gtk_app_chooser_online_get_type ())
+#define GTK_APP_CHOOSER_ONLINE(o)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_APP_CHOOSER_ONLINE, GtkAppChooserOnline))
+#define GTK_IS_APP_CHOOSER_ONLINE(o)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_APP_CHOOSER_ONLINE))
+#define GTK_APP_CHOOSER_ONLINE_GET_IFACE(obj)\
+ (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_APP_CHOOSER_ONLINE, GtkAppChooserOnlineInterface))
+
+typedef struct _GtkAppChooserOnline GtkAppChooserOnline;
+typedef struct _GtkAppChooserOnlineInterface GtkAppChooserOnlineInterface;
+
+struct _GtkAppChooserOnlineInterface {
+ GTypeInterface g_iface;
+
+ /* Methods */
+ void (*search_for_mimetype_async) (GtkAppChooserOnline *self,
+ const gchar *content_type,
+ GtkWindow *parent,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ gboolean (*search_for_mimetype_finish) (GtkAppChooserOnline *self,
+ GAsyncResult *res,
+ GError **error);
+};
+
+GType gtk_app_chooser_online_get_type (void) G_GNUC_CONST;
+void gtk_app_chooser_online_search_for_mimetype_async (GtkAppChooserOnline *self,
+ const gchar *content_type,
+ GtkWindow *parent,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean gtk_app_chooser_online_search_for_mimetype_finish (GtkAppChooserOnline *self,
+ GAsyncResult *res,
+ GError **error);
+
+GtkAppChooserOnline * gtk_app_chooser_online_get_default (void);
+
+#endif /* __GTK_APP_CHOOSER_ONLINE_H__ */
--- /dev/null
+/*
+ * gtkappchooseronlinedummy.c: an extension point for online integration
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#include <config.h>
+
+#include "gtkappchooseronlinedummy.h"
+
+#include "gtkintl.h"
+#include "gtkappchooseronline.h"
+
+#include <gio/gio.h>
+
+#define gtk_app_chooser_online_dummy_get_type _gtk_app_chooser_online_dummy_get_type
+static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlineDummy, gtk_app_chooser_online_dummy,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE,
+ app_chooser_online_iface_init)
+ g_io_extension_point_implement ("gtkappchooser-online",
+ g_define_type_id,
+ "dummy", 0));
+
+static void
+gtk_app_chooser_online_dummy_class_init (GtkAppChooserOnlineDummyClass *klass)
+{
+ /* do nothing */
+}
+
+static void
+gtk_app_chooser_online_dummy_init (GtkAppChooserOnlineDummy *self)
+{
+ /* do nothing */
+}
+
+static gboolean
+dummy_search_mime_finish (GtkAppChooserOnline *obj,
+ GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+dummy_search_mime_async (GtkAppChooserOnline *obj,
+ const gchar *content_type,
+ GtkWindow *parent,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_simple_async_report_error_in_idle (G_OBJECT (obj),
+ callback, user_data,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "%s",
+ _("Operation not supported"));
+}
+
+static void
+app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
+{
+ iface->search_for_mimetype_async = dummy_search_mime_async;
+ iface->search_for_mimetype_finish = dummy_search_mime_finish;
+}
--- /dev/null
+/*
+ * gtkappchooseronlinedummy.h: an extension point for online integration
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#ifndef __GTK_APP_CHOOSER_ONLINE_DUMMY_H__
+#define __GTK_APP_CHOOSER_ONLINE_DUMMY_H__
+
+#include <gtk/gtkappchooseronline.h>
+#include <glib.h>
+
+#define GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY\
+ (_gtk_app_chooser_online_dummy_get_type ())
+#define GTK_APP_CHOOSER_ONLINE_DUMMY(obj)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummy))
+#define GTK_APP_CHOOSER_ONLINE_DUMMY_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummyClass))
+#define GTK_IS_APP_CHOOSER_ONLINE_DUMMY(obj)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY))
+#define GTK_IS_APP_CHOOSER_ONLINE_DUMMY_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY))
+#define GTK_APP_CHOOSER_ONLINE_DUMMY_GET_CLASS(obj)\
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummyClass))
+
+typedef struct _GtkAppChooserOnlineDummy GtkAppChooserOnlineDummy;
+typedef struct _GtkAppChooserOnlineDummyClass GtkAppChooserOnlineDummyClass;
+typedef struct _GtkAppChooserOnlineDummyPrivate GtkAppChooserOnlineDummyPrivate;
+
+struct _GtkAppChooserOnlineDummy {
+ GObject parent;
+};
+
+struct _GtkAppChooserOnlineDummyClass {
+ GObjectClass parent_class;
+
+ GtkAppChooserOnlineDummy *priv;
+};
+
+GType _gtk_app_chooser_online_dummy_get_type (void);
+
+#endif /* __GTK_APP_CHOOSER_ONLINE_DUMMY_H__ */
--- /dev/null
+/*
+ * gtkappchooseronlinepk.c: packagekit module for app-chooser
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#include <config.h>
+
+#include "gtkappchooseronlinepk.h"
+
+#include "gtkappchooseronline.h"
+#include "x11/gdkx.h"
+
+#include <gio/gio.h>
+
+#define gtk_app_chooser_online_pk_get_type _gtk_app_chooser_online_pk_get_type
+static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlinePk, gtk_app_chooser_online_pk,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE,
+ app_chooser_online_iface_init)
+ g_io_extension_point_implement ("gtkappchooser-online",
+ g_define_type_id,
+ "packagekit", 10));
+
+struct _GtkAppChooserOnlinePkPrivate {
+ GSimpleAsyncResult *result;
+ GtkWindow *parent;
+ gchar *content_type;
+};
+
+static void
+gtk_app_chooser_online_pk_finalize (GObject *obj)
+{
+ GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
+
+ g_free (self->priv->content_type);
+ g_clear_object (&self->priv->result);
+
+ G_OBJECT_CLASS (gtk_app_chooser_online_pk_parent_class)->finalize (obj);
+}
+
+static void
+gtk_app_chooser_online_pk_class_init (GtkAppChooserOnlinePkClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+ oclass->finalize = gtk_app_chooser_online_pk_finalize;
+
+ g_type_class_add_private (klass, sizeof (GtkAppChooserOnlinePkPrivate));
+}
+
+static void
+gtk_app_chooser_online_pk_init (GtkAppChooserOnlinePk *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_APP_CHOOSER_ONLINE_PK,
+ GtkAppChooserOnlinePkPrivate);
+}
+
+static gboolean
+pk_search_mime_finish (GtkAppChooserOnline *obj,
+ GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+install_mime_types_ready_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkAppChooserOnlinePk *self = user_data;
+ GDBusProxy *proxy = G_DBUS_PROXY (source);
+ GError *error = NULL;
+ GVariant *variant;
+
+ variant = g_dbus_proxy_call_finish (proxy, res, &error);
+
+ if (variant == NULL) {
+ /* don't show errors if the user cancelled the installation explicitely
+ * or if PK wasn't able to find any apps
+ */
+ if (g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.Cancelled") != 0 &&
+ g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.NoPackagesFound") != 0)
+ g_simple_async_result_set_from_error (self->priv->result, error);
+
+ g_error_free (error);
+ }
+
+ g_simple_async_result_complete (self->priv->result);
+}
+
+static void
+pk_proxy_appeared_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkAppChooserOnlinePk *self = user_data;
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ guint xid = 0;
+ GdkWindow *window;
+ const gchar *mime_types[2];
+
+ proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (self->priv->result, error);
+ g_error_free (error);
+
+ g_simple_async_result_complete (self->priv->result);
+
+ return;
+ }
+
+ window = gtk_widget_get_window (GTK_WIDGET (self->priv->parent));
+ xid = GDK_WINDOW_XID (window);
+
+ mime_types[0] = self->priv->content_type;
+ mime_types[1] = NULL;
+
+ g_dbus_proxy_call (proxy,
+ "InstallMimeTypes",
+ g_variant_new ("(u^ass)",
+ xid,
+ mime_types,
+ "hide-confirm-search"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT, /* no timeout */
+ NULL,
+ install_mime_types_ready_cb,
+ self);
+}
+
+static void
+pk_search_mime_async (GtkAppChooserOnline *obj,
+ const gchar *content_type,
+ GtkWindow *parent,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
+
+ self->priv->result = g_simple_async_result_new (G_OBJECT (self),
+ callback, user_data,
+ gtk_app_chooser_online_search_for_mimetype_async);
+ self->priv->parent = parent;
+ self->priv->content_type = g_strdup (content_type);
+
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.freedesktop.PackageKit",
+ "/org/freedesktop/PackageKit",
+ "org.freedesktop.PackageKit.Modify",
+ NULL,
+ pk_proxy_appeared_cb,
+ self);
+}
+
+static void
+app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
+{
+ iface->search_for_mimetype_async = pk_search_mime_async;
+ iface->search_for_mimetype_finish = pk_search_mime_finish;
+}
--- /dev/null
+/*
+ * gtkappchooseronlinepk.h: an extension point for online integration
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#ifndef __GTK_APP_CHOOSER_ONLINE_PK_H__
+#define __GTK_APP_CHOOSER_ONLINE_PK_H__
+
+#include <gtk/gtkappchooseronline.h>
+#include <glib.h>
+
+#define GTK_TYPE_APP_CHOOSER_ONLINE_PK\
+ (_gtk_app_chooser_online_pk_get_type ())
+#define GTK_APP_CHOOSER_ONLINE_PK(obj)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_PK, GtkAppChooserOnlinePk))
+#define GTK_APP_CHOOSER_ONLINE_PK_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_APP_CHOOSER_ONLINE_PK, GtkAppChooserOnlinePkClass))
+#define GTK_IS_APP_CHOOSER_ONLINE_PK(obj)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_PK))
+#define GTK_IS_APP_CHOOSER_ONLINE_PK_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_APP_CHOOSER_ONLINE_PK))
+#define GTK_APP_CHOOSER_ONLINE_PK_GET_CLASS(obj)\
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_PK, GtkAppChooserOnlinePkClass))
+
+typedef struct _GtkAppChooserOnlinePk GtkAppChooserOnlinePk;
+typedef struct _GtkAppChooserOnlinePkClass GtkAppChooserOnlinePkClass;
+typedef struct _GtkAppChooserOnlinePkPrivate GtkAppChooserOnlinePkPrivate;
+
+struct _GtkAppChooserOnlinePk {
+ GObject parent;
+
+ GtkAppChooserOnlinePkPrivate *priv;
+};
+
+struct _GtkAppChooserOnlinePkClass {
+ GObjectClass parent_class;
+};
+
+GType _gtk_app_chooser_online_pk_get_type (void);
+
+#endif /* __GTK_APP_CHOOSER_ONLINE_PK_H__ */
--- /dev/null
+/*
+ * gtkappchooserprivate.h: app-chooser interface
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#ifndef __GTK_APP_CHOOSER_PRIVATE_H__
+#define __GTK_APP_CHOOSER_PRIVATE_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "gtkappchooserwidget.h"
+
+typedef struct _GtkAppChooserIface GtkAppChooserIface;
+typedef GtkAppChooserIface GtkAppChooserInterface;
+
+#define GTK_APP_CHOOSER_GET_IFACE(inst)\
+ (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_APP_CHOOSER, GtkAppChooserIface))
+
+struct _GtkAppChooserIface {
+ GTypeInterface base_iface;
+
+ GAppInfo * (* get_app_info) (GtkAppChooser *object);
+ void (* refresh) (GtkAppChooser *object);
+};
+
+#endif /* __GTK_APP_CHOOSER_PRIVATE_H__ */
--- /dev/null
+/*
+ * gtkappchooserwidget.c: an app-chooser widget
+ *
+ * Copyright (C) 2004 Novell, Inc.
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Dave Camp <dave@novell.com>
+ * Alexander Larsson <alexl@redhat.com>
+ * Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#include <config.h>
+
+#include "gtkappchooserwidget.h"
+
+#include "gtkintl.h"
+#include "gtkmarshalers.h"
+#include "gtkappchooser.h"
+#include "gtkappchooserprivate.h"
+
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+struct _GtkAppChooserWidgetPrivate {
+ GAppInfo *selected_app_info;
+
+ gchar *content_type;
+ gchar *default_text;
+ gboolean show_default;
+ gboolean show_recommended;
+ gboolean show_fallback;
+ gboolean show_other;
+ gboolean show_all;
+
+ GtkWidget *program_list;
+ GtkListStore *program_list_store;
+
+ GtkCellRenderer *padding_renderer;
+};
+
+enum {
+ COLUMN_APP_INFO,
+ COLUMN_GICON,
+ COLUMN_NAME,
+ COLUMN_DESC,
+ COLUMN_EXEC,
+ COLUMN_DEFAULT,
+ COLUMN_HEADING,
+ COLUMN_HEADING_TEXT,
+ COLUMN_RECOMMENDED,
+ COLUMN_FALLBACK,
+ NUM_COLUMNS
+};
+
+
+enum {
+ PROP_CONTENT_TYPE = 1,
+ PROP_GFILE,
+ PROP_SHOW_DEFAULT,
+ PROP_SHOW_RECOMMENDED,
+ PROP_SHOW_FALLBACK,
+ PROP_SHOW_OTHER,
+ PROP_SHOW_ALL,
+ PROP_DEFAULT_TEXT,
+ N_PROPERTIES
+};
+
+enum {
+ SIGNAL_APPLICATION_SELECTED,
+ SIGNAL_APPLICATION_ACTIVATED,
+ N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0, };
+
+static void gtk_app_chooser_widget_iface_init (GtkAppChooserIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkAppChooserWidget, gtk_app_chooser_widget, GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER,
+ gtk_app_chooser_widget_iface_init));
+
+static void
+refresh_and_emit_app_selected (GtkAppChooserWidget *self,
+ GtkTreeSelection *selection)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GAppInfo *info = NULL;
+ gboolean should_emit = FALSE;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gtk_tree_model_get (model, &iter,
+ COLUMN_APP_INFO, &info,
+ -1);
+ }
+
+ if (info == NULL)
+ return;
+
+ if (self->priv->selected_app_info != NULL)
+ {
+ if (!g_app_info_equal (self->priv->selected_app_info, info))
+ {
+ should_emit = TRUE;
+ g_object_unref (self->priv->selected_app_info);
+
+ self->priv->selected_app_info = info;
+ }
+ }
+ else
+ {
+ should_emit = TRUE;
+ self->priv->selected_app_info = info;
+ }
+
+ if (should_emit)
+ g_signal_emit (self, signals[SIGNAL_APPLICATION_SELECTED], 0,
+ self->priv->selected_app_info);
+}
+
+static gboolean
+path_is_heading (GtkTreeView *view,
+ GtkTreePath *path)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gboolean res;
+
+ model = gtk_tree_view_get_model (view);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter,
+ COLUMN_HEADING, &res,
+ -1);
+
+ return res;
+}
+
+static void
+program_list_selection_activated (GtkTreeView *view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ gpointer user_data)
+{
+ GtkAppChooserWidget *self = user_data;
+ GtkTreeSelection *selection;
+
+ if (path_is_heading (view, path))
+ return;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
+
+ refresh_and_emit_app_selected (self, selection);
+
+ g_signal_emit (self, signals[SIGNAL_APPLICATION_ACTIVATED], 0,
+ self->priv->selected_app_info);
+}
+
+static gboolean
+gtk_app_chooser_search_equal_func (GtkTreeModel *model,
+ int column,
+ const char *key,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ char *normalized_key;
+ char *name, *normalized_name;
+ char *path, *normalized_path;
+ char *basename, *normalized_basename;
+ gboolean ret;
+
+ if (key != NULL)
+ {
+ normalized_key = g_utf8_casefold (key, -1);
+ g_assert (normalized_key != NULL);
+
+ ret = TRUE;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_NAME, &name,
+ COLUMN_EXEC, &path,
+ -1);
+
+ if (name != NULL)
+ {
+ normalized_name = g_utf8_casefold (name, -1);
+ g_assert (normalized_name != NULL);
+
+ if (strncmp (normalized_name, normalized_key, strlen (normalized_key)) == 0) {
+ ret = FALSE;
+ }
+
+ g_free (normalized_name);
+ }
+
+ if (ret && path != NULL)
+ {
+ normalized_path = g_utf8_casefold (path, -1);
+ g_assert (normalized_path != NULL);
+
+ basename = g_path_get_basename (path);
+ g_assert (basename != NULL);
+
+ normalized_basename = g_utf8_casefold (basename, -1);
+ g_assert (normalized_basename != NULL);
+
+ if (strncmp (normalized_path, normalized_key, strlen (normalized_key)) == 0 ||
+ strncmp (normalized_basename, normalized_key, strlen (normalized_key)) == 0) {
+ ret = FALSE;
+ }
+
+ g_free (basename);
+ g_free (normalized_basename);
+ g_free (normalized_path);
+ }
+
+ g_free (name);
+ g_free (path);
+ g_free (normalized_key);
+
+ return ret;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+static gint
+gtk_app_chooser_sort_func (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
+{
+ gboolean a_recommended, b_recommended;
+ gboolean a_fallback, b_fallback;
+ gboolean a_heading, b_heading;
+ gboolean a_default, b_default;
+ gchar *a_name, *b_name, *a_casefold, *b_casefold;
+ gint retval = 0;
+
+ /* this returns:
+ * - <0 if a should show before b
+ * - =0 if a is the same as b
+ * - >0 if a should show after b
+ */
+
+ gtk_tree_model_get (model, a,
+ COLUMN_NAME, &a_name,
+ COLUMN_RECOMMENDED, &a_recommended,
+ COLUMN_FALLBACK, &a_fallback,
+ COLUMN_HEADING, &a_heading,
+ COLUMN_DEFAULT, &a_default,
+ -1);
+
+ gtk_tree_model_get (model, b,
+ COLUMN_NAME, &b_name,
+ COLUMN_RECOMMENDED, &b_recommended,
+ COLUMN_FALLBACK, &b_fallback,
+ COLUMN_HEADING, &b_heading,
+ COLUMN_DEFAULT, &b_default,
+ -1);
+
+ /* the default one always wins */
+ if (a_default && !b_default)
+ {
+ retval = -1;
+ goto out;
+ }
+
+ if (b_default && !a_default)
+ {
+ retval = 1;
+ goto out;
+ }
+
+ /* the recommended one always wins */
+ if (a_recommended && !b_recommended)
+ {
+ retval = -1;
+ goto out;
+ }
+
+ if (b_recommended && !a_recommended)
+ {
+ retval = 1;
+ goto out;
+ }
+
+ /* the recommended one always wins */
+ if (a_fallback && !b_fallback)
+ {
+ retval = -1;
+ goto out;
+ }
+
+ if (b_fallback && !a_fallback)
+ {
+ retval = 1;
+ goto out;
+ }
+
+ /* they're both recommended/falback or not, so if one is a heading, wins */
+ if (a_heading)
+ {
+ return -1;
+ goto out;
+ }
+
+ if (b_heading)
+ {
+ return 1;
+ goto out;
+ }
+
+ /* don't order by name recommended applications, but use GLib's ordering */
+ if (!a_recommended)
+ {
+ a_casefold = a_name != NULL ?
+ g_utf8_casefold (a_name, -1) : NULL;
+ b_casefold = b_name != NULL ?
+ g_utf8_casefold (b_name, -1) : NULL;
+
+ retval = g_strcmp0 (a_casefold, b_casefold);
+
+ g_free (a_casefold);
+ g_free (b_casefold);
+ }
+
+ out:
+ g_free (a_name);
+ g_free (b_name);
+
+ return retval;
+}
+
+static void
+padding_cell_renderer_func (GtkTreeViewColumn *column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ gboolean heading;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_HEADING, &heading,
+ -1);
+ if (heading)
+ g_object_set (cell,
+ "visible", FALSE,
+ "xpad", 0,
+ "ypad", 0,
+ NULL);
+ else
+ g_object_set (cell,
+ "visible", TRUE,
+ "xpad", 3,
+ "ypad", 3,
+ NULL);
+}
+
+static gboolean
+gtk_app_chooser_selection_func (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean path_currently_selected,
+ gpointer user_data)
+{
+ GtkTreeIter iter;
+ gboolean heading;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter,
+ COLUMN_HEADING, &heading,
+ -1);
+
+ return !heading;
+}
+
+static gint
+compare_apps_func (gconstpointer a,
+ gconstpointer b)
+{
+ return !g_app_info_equal (G_APP_INFO (a), G_APP_INFO (b));
+}
+
+static gboolean
+gtk_app_chooser_widget_add_section (GtkAppChooserWidget *self,
+ const gchar *heading_title,
+ gboolean show_headings,
+ gboolean recommended,
+ gboolean fallback,
+ GList *applications,
+ GList *exclude_apps)
+{
+ gboolean heading_added, unref_icon;
+ GtkTreeIter iter;
+ GAppInfo *app;
+ gchar *app_string, *bold_string;
+ GIcon *icon;
+ GList *l;
+ gboolean retval;
+
+ retval = FALSE;
+ heading_added = FALSE;
+ bold_string = g_strdup_printf ("<b>%s</b>", heading_title);
+
+ for (l = applications; l != NULL; l = l->next)
+ {
+ app = l->data;
+
+ if (exclude_apps != NULL &&
+ g_list_find_custom (exclude_apps, app,
+ (GCompareFunc) compare_apps_func))
+ continue;
+
+ if (!heading_added && show_headings)
+ {
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_HEADING_TEXT, bold_string,
+ COLUMN_HEADING, TRUE,
+ COLUMN_RECOMMENDED, recommended,
+ COLUMN_FALLBACK, fallback,
+ -1);
+
+ heading_added = TRUE;
+ }
+
+ app_string = g_strdup_printf ("<b>%s</b>\n%s",
+ g_app_info_get_display_name (app) != NULL ?
+ g_app_info_get_display_name (app) : "",
+ g_app_info_get_description (app) != NULL ?
+ g_app_info_get_description (app) : "");
+
+ icon = g_app_info_get_icon (app);
+ if (icon == NULL)
+ {
+ icon = g_themed_icon_new ("application-x-executable");
+ unref_icon = TRUE;
+ }
+
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_APP_INFO, app,
+ COLUMN_GICON, icon,
+ COLUMN_NAME, g_app_info_get_display_name (app),
+ COLUMN_DESC, app_string,
+ COLUMN_EXEC, g_app_info_get_executable (app),
+ COLUMN_HEADING, FALSE,
+ COLUMN_RECOMMENDED, recommended,
+ COLUMN_FALLBACK, fallback,
+ -1);
+
+ retval = TRUE;
+
+ g_free (app_string);
+ if (unref_icon)
+ g_object_unref (icon);
+
+ unref_icon = FALSE;
+ }
+
+ g_free (bold_string);
+
+ return retval;
+}
+
+
+static void
+gtk_app_chooser_add_default (GtkAppChooserWidget *self,
+ GAppInfo *app)
+{
+ GtkTreeIter iter;
+ GIcon *icon;
+ gchar *string;
+ gboolean unref_icon;
+
+ unref_icon = FALSE;
+ string = g_strdup_printf ("<b>%s</b>", _("Default Application"));
+
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_HEADING_TEXT, string,
+ COLUMN_HEADING, TRUE,
+ COLUMN_DEFAULT, TRUE,
+ -1);
+
+ g_free (string);
+
+ string = g_strdup_printf ("<b>%s</b>\n%s",
+ g_app_info_get_display_name (app) != NULL ?
+ g_app_info_get_display_name (app) : "",
+ g_app_info_get_description (app) != NULL ?
+ g_app_info_get_description (app) : "");
+
+ icon = g_app_info_get_icon (app);
+ if (icon == NULL)
+ {
+ icon = g_themed_icon_new ("application-x-executable");
+ unref_icon = TRUE;
+ }
+
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_APP_INFO, app,
+ COLUMN_GICON, icon,
+ COLUMN_NAME, g_app_info_get_display_name (app),
+ COLUMN_DESC, string,
+ COLUMN_EXEC, g_app_info_get_executable (app),
+ COLUMN_HEADING, FALSE,
+ COLUMN_DEFAULT, TRUE,
+ -1);
+
+ g_free (string);
+
+ if (unref_icon)
+ g_object_unref (icon);
+}
+
+static void
+add_no_applications_label (GtkAppChooserWidget *self)
+{
+ gchar *text = NULL, *desc;
+ const gchar *string;
+ GtkTreeIter iter;
+
+ if (self->priv->default_text == NULL)
+ {
+ desc = g_content_type_get_description (self->priv->content_type);
+ string = text = g_strdup_printf (_("No applications available to open \"%s\""),
+ desc);
+ g_free (desc);
+ }
+ else
+ {
+ string = self->priv->default_text;
+ }
+
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_HEADING_TEXT, string,
+ COLUMN_HEADING, TRUE,
+ -1);
+
+ g_free (text);
+}
+
+static void
+gtk_app_chooser_widget_select_first (GtkAppChooserWidget *self)
+{
+ GtkTreeIter iter;
+ GAppInfo *info = NULL;
+ GtkTreeModel *model;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->program_list));
+ gtk_tree_model_get_iter_first (model, &iter);
+
+ while (info == NULL)
+ {
+ gtk_tree_model_get (model, &iter,
+ COLUMN_APP_INFO, &info,
+ -1);
+
+ if (info != NULL)
+ break;
+
+ if (!gtk_tree_model_iter_next (model, &iter))
+ break;
+ }
+
+ if (info != NULL)
+ {
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
+ gtk_tree_selection_select_iter (selection, &iter);
+
+ g_object_unref (info);
+ }
+}
+
+static void
+gtk_app_chooser_widget_real_add_items (GtkAppChooserWidget *self)
+{
+ GList *all_applications = NULL, *recommended_apps = NULL, *fallback_apps = NULL;
+ GList *exclude_apps = NULL;
+ GAppInfo *default_app = NULL;
+ gboolean show_headings;
+ gboolean apps_added;
+
+ show_headings = TRUE;
+ apps_added = FALSE;
+
+ if (self->priv->show_all)
+ show_headings = FALSE;
+
+ if (self->priv->show_default)
+ {
+ default_app = g_app_info_get_default_for_type (self->priv->content_type, FALSE);
+
+ if (default_app != NULL)
+ {
+ gtk_app_chooser_add_default (self, default_app);
+ apps_added = TRUE;
+ exclude_apps = g_list_prepend (exclude_apps, default_app);
+ }
+ }
+
+ if (self->priv->show_recommended || self->priv->show_all)
+ {
+ recommended_apps = g_app_info_get_recommended_for_type (self->priv->content_type);
+
+ apps_added |= gtk_app_chooser_widget_add_section (self, _("Recommended Applications"),
+ show_headings,
+ !self->priv->show_all, /* mark as recommended */
+ FALSE, /* mark as fallback */
+ recommended_apps, exclude_apps);
+
+ exclude_apps = g_list_concat (exclude_apps,
+ g_list_copy (recommended_apps));
+ }
+
+ if (self->priv->show_fallback || self->priv->show_all)
+ {
+ fallback_apps = g_app_info_get_fallback_for_type (self->priv->content_type);
+
+ apps_added |= gtk_app_chooser_widget_add_section (self, _("Related Applications"),
+ show_headings,
+ FALSE, /* mark as recommended */
+ !self->priv->show_all, /* mark as fallback */
+ fallback_apps, exclude_apps);
+ exclude_apps = g_list_concat (exclude_apps,
+ g_list_copy (fallback_apps));
+ }
+
+ if (self->priv->show_other || self->priv->show_all)
+ {
+ all_applications = g_app_info_get_all ();
+
+ apps_added |= gtk_app_chooser_widget_add_section (self, _("Other Applications"),
+ show_headings,
+ FALSE,
+ FALSE,
+ all_applications, exclude_apps);
+ }
+
+ if (!apps_added)
+ add_no_applications_label (self);
+
+ gtk_app_chooser_widget_select_first (self);
+
+ if (default_app != NULL)
+ g_object_unref (default_app);
+
+ if (all_applications != NULL)
+ g_list_free_full (all_applications, g_object_unref);
+
+ if (recommended_apps != NULL)
+ g_list_free_full (recommended_apps, g_object_unref);
+
+ if (fallback_apps != NULL)
+ g_list_free_full (fallback_apps, g_object_unref);
+
+ if (exclude_apps != NULL)
+ g_list_free (exclude_apps);
+}
+
+static void
+gtk_app_chooser_widget_add_items (GtkAppChooserWidget *self)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeModel *sort;
+
+ /* create list store */
+ self->priv->program_list_store = gtk_list_store_new (NUM_COLUMNS,
+ G_TYPE_APP_INFO,
+ G_TYPE_ICON,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN);
+ sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->priv->program_list_store));
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (self->priv->program_list),
+ GTK_TREE_MODEL (sort));
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort),
+ COLUMN_NAME,
+ GTK_SORT_ASCENDING);
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort),
+ COLUMN_NAME,
+ gtk_app_chooser_sort_func,
+ self, NULL);
+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (self->priv->program_list),
+ COLUMN_NAME);
+ gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->priv->program_list),
+ gtk_app_chooser_search_equal_func,
+ NULL, NULL);
+
+ column = gtk_tree_view_column_new ();
+
+ /* initial padding */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ g_object_set (renderer,
+ "xpad", self->priv->show_all ? 0 : 6,
+ NULL);
+ self->priv->padding_renderer = renderer;
+
+ /* heading text renderer */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "markup", COLUMN_HEADING_TEXT,
+ "visible", COLUMN_HEADING,
+ NULL);
+ g_object_set (renderer,
+ "ypad", 6,
+ "xpad", 0,
+ "wrap-width", 350,
+ "wrap-mode", PANGO_WRAP_WORD,
+ NULL);
+
+ /* padding renderer for non-heading cells */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer,
+ padding_cell_renderer_func,
+ NULL, NULL);
+
+ /* app icon renderer */
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "gicon", COLUMN_GICON,
+ NULL);
+ g_object_set (renderer,
+ "stock-size", GTK_ICON_SIZE_DIALOG,
+ NULL);
+
+ /* app name renderer */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "markup", COLUMN_DESC,
+ NULL);
+ g_object_set (renderer,
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ "ellipsize-set", TRUE,
+ NULL);
+
+ gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->program_list), column);
+
+ /* populate the widget */
+ gtk_app_chooser_widget_real_add_items (self);
+}
+
+static void
+gtk_app_chooser_widget_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (object);
+
+ switch (property_id)
+ {
+ case PROP_CONTENT_TYPE:
+ self->priv->content_type = g_value_dup_string (value);
+ break;
+ case PROP_SHOW_DEFAULT:
+ gtk_app_chooser_widget_set_show_default (self, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_RECOMMENDED:
+ gtk_app_chooser_widget_set_show_recommended (self, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_FALLBACK:
+ gtk_app_chooser_widget_set_show_fallback (self, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_OTHER:
+ gtk_app_chooser_widget_set_show_other (self, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_ALL:
+ gtk_app_chooser_widget_set_show_all (self, g_value_get_boolean (value));
+ break;
+ case PROP_DEFAULT_TEXT:
+ gtk_app_chooser_widget_set_default_text (self, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_app_chooser_widget_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (object);
+
+ switch (property_id)
+ {
+ case PROP_CONTENT_TYPE:
+ g_value_set_string (value, self->priv->content_type);
+ break;
+ case PROP_SHOW_DEFAULT:
+ g_value_set_boolean (value, self->priv->show_default);
+ break;
+ case PROP_SHOW_RECOMMENDED:
+ g_value_set_boolean (value, self->priv->show_recommended);
+ break;
+ case PROP_SHOW_FALLBACK:
+ g_value_set_boolean (value, self->priv->show_fallback);
+ break;
+ case PROP_SHOW_OTHER:
+ g_value_set_boolean (value, self->priv->show_other);
+ break;
+ case PROP_SHOW_ALL:
+ g_value_set_boolean (value, self->priv->show_all);
+ break;
+ case PROP_DEFAULT_TEXT:
+ g_value_set_string (value, self->priv->default_text);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_app_chooser_widget_constructed (GObject *object)
+{
+ GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (object);
+
+ g_assert (self->priv->content_type != NULL);
+
+ if (G_OBJECT_CLASS (gtk_app_chooser_widget_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (gtk_app_chooser_widget_parent_class)->constructed (object);
+
+ gtk_app_chooser_widget_add_items (self);
+}
+
+static void
+gtk_app_chooser_widget_finalize (GObject *object)
+{
+ GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (object);
+
+ g_free (self->priv->content_type);
+ g_free (self->priv->default_text);
+
+ G_OBJECT_CLASS (gtk_app_chooser_widget_parent_class)->finalize (object);
+}
+
+static void
+gtk_app_chooser_widget_dispose (GObject *object)
+{
+ GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (object);
+
+ if (self->priv->selected_app_info != NULL)
+ {
+ g_object_unref (self->priv->selected_app_info);
+ self->priv->selected_app_info = NULL;
+ }
+
+ G_OBJECT_CLASS (gtk_app_chooser_widget_parent_class)->dispose (object);
+}
+
+static void
+gtk_app_chooser_widget_class_init (GtkAppChooserWidgetClass *klass)
+{
+ GObjectClass *gobject_class;
+ GParamSpec *pspec;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->dispose = gtk_app_chooser_widget_dispose;
+ gobject_class->finalize = gtk_app_chooser_widget_finalize;
+ gobject_class->set_property = gtk_app_chooser_widget_set_property;
+ gobject_class->get_property = gtk_app_chooser_widget_get_property;
+ gobject_class->constructed = gtk_app_chooser_widget_constructed;
+
+ g_object_class_override_property (gobject_class, PROP_CONTENT_TYPE, "content-type");
+
+ pspec = g_param_spec_boolean ("show-default",
+ P_("Show default app"),
+ P_("Whether the widget should show the default application"),
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_SHOW_DEFAULT, pspec);
+
+ pspec = g_param_spec_boolean ("show-recommended",
+ P_("Show recommended apps"),
+ P_("Whether the widget should show recommended applications"),
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_SHOW_RECOMMENDED, pspec);
+
+ pspec = g_param_spec_boolean ("show-fallback",
+ P_("Show fallback apps"),
+ P_("Whether the widget should show fallback applications"),
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_SHOW_FALLBACK, pspec);
+
+ pspec = g_param_spec_boolean ("show-other",
+ P_("Show other apps"),
+ P_("Whether the widget should show other applications"),
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_SHOW_OTHER, pspec);
+
+ pspec = g_param_spec_boolean ("show-all",
+ P_("Show all apps"),
+ P_("Whether the widget should show all applications"),
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_SHOW_ALL, pspec);
+
+ pspec = g_param_spec_string ("default-text",
+ P_("Widget's default text"),
+ P_("The default text appearing when there are no applications"),
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_DEFAULT_TEXT, pspec);
+
+ signals[SIGNAL_APPLICATION_SELECTED] =
+ g_signal_new ("application-selected",
+ GTK_TYPE_APP_CHOOSER_WIDGET,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkAppChooserWidgetClass, application_selected),
+ NULL, NULL,
+ _gtk_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, G_TYPE_APP_INFO);
+
+ signals[SIGNAL_APPLICATION_ACTIVATED] =
+ g_signal_new ("application-activated",
+ GTK_TYPE_APP_CHOOSER_WIDGET,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkAppChooserWidgetClass, application_activated),
+ NULL, NULL,
+ _gtk_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, G_TYPE_APP_INFO);
+
+ g_type_class_add_private (klass, sizeof (GtkAppChooserWidgetPrivate));
+}
+
+static void
+gtk_app_chooser_widget_init (GtkAppChooserWidget *self)
+{
+ GtkWidget *scrolled_window;
+ GtkTreeSelection *selection;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_APP_CHOOSER_WIDGET,
+ GtkAppChooserWidgetPrivate);
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_set_size_request (scrolled_window, 400, 300);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_widget_show (scrolled_window);
+
+ self->priv->program_list = gtk_tree_view_new ();
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->priv->program_list),
+ FALSE);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), self->priv->program_list);
+ gtk_box_pack_start (GTK_BOX (self), scrolled_window, TRUE, TRUE, 0);
+ gtk_widget_show (self->priv->program_list);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+ gtk_tree_selection_set_select_function (selection, gtk_app_chooser_selection_func,
+ self, NULL);
+ g_signal_connect_swapped (selection, "changed",
+ G_CALLBACK (refresh_and_emit_app_selected),
+ self);
+ g_signal_connect (self->priv->program_list, "row-activated",
+ G_CALLBACK (program_list_selection_activated),
+ self);
+}
+
+static GAppInfo *
+gtk_app_chooser_widget_get_app_info (GtkAppChooser *object)
+{
+ GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (object);
+
+ if (self->priv->selected_app_info == NULL)
+ return NULL;
+
+ return g_object_ref (self->priv->selected_app_info);
+}
+
+static void
+gtk_app_chooser_widget_refresh (GtkAppChooser *object)
+{
+ GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (object);
+
+ if (self->priv->program_list_store != NULL)
+ {
+ gtk_list_store_clear (self->priv->program_list_store);
+
+ /* don't add additional xpad if we don't have headings */
+ g_object_set (self->priv->padding_renderer,
+ "visible", !self->priv->show_all,
+ NULL);
+
+ gtk_app_chooser_widget_real_add_items (self);
+ }
+}
+
+static void
+gtk_app_chooser_widget_iface_init (GtkAppChooserIface *iface)
+{
+ iface->get_app_info = gtk_app_chooser_widget_get_app_info;
+ iface->refresh = gtk_app_chooser_widget_refresh;
+}
+
+GtkWidget *
+gtk_app_chooser_widget_new (const gchar *content_type)
+{
+ return g_object_new (GTK_TYPE_APP_CHOOSER_WIDGET,
+ "content-type", content_type,
+ NULL);
+}
+
+void
+gtk_app_chooser_widget_set_show_default (GtkAppChooserWidget *self,
+ gboolean setting)
+{
+ g_return_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self));
+
+ if (self->priv->show_default != setting)
+ {
+ self->priv->show_default = setting;
+
+ g_object_notify (G_OBJECT (self), "show-default");
+
+ gtk_app_chooser_refresh (GTK_APP_CHOOSER (self));
+ }
+}
+
+gboolean
+gtk_app_chooser_widget_get_show_default (GtkAppChooserWidget *self)
+{
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self), FALSE);
+
+ return self->priv->show_default;
+}
+
+void
+gtk_app_chooser_widget_set_show_recommended (GtkAppChooserWidget *self,
+ gboolean setting)
+{
+ g_return_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self));
+
+ if (self->priv->show_recommended != setting)
+ {
+ self->priv->show_recommended = setting;
+
+ g_object_notify (G_OBJECT (self), "show-recommended");
+
+ gtk_app_chooser_refresh (GTK_APP_CHOOSER (self));
+ }
+}
+
+gboolean
+gtk_app_chooser_widget_get_show_recommended (GtkAppChooserWidget *self)
+{
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self), FALSE);
+
+ return self->priv->show_recommended;
+}
+
+void
+gtk_app_chooser_widget_set_show_fallback (GtkAppChooserWidget *self,
+ gboolean setting)
+{
+ g_return_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self));
+
+ if (self->priv->show_fallback != setting)
+ {
+ self->priv->show_fallback = setting;
+
+ g_object_notify (G_OBJECT (self), "show-fallback");
+
+ gtk_app_chooser_refresh (GTK_APP_CHOOSER (self));
+ }
+}
+
+gboolean
+gtk_app_chooser_widget_get_show_fallback (GtkAppChooserWidget *self)
+{
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self), FALSE);
+
+ return self->priv->show_fallback;
+}
+
+void
+gtk_app_chooser_widget_set_show_other (GtkAppChooserWidget *self,
+ gboolean setting)
+{
+ g_return_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self));
+
+ if (self->priv->show_other != setting)
+ {
+ self->priv->show_other = setting;
+
+ g_object_notify (G_OBJECT (self), "show-other");
+
+ gtk_app_chooser_refresh (GTK_APP_CHOOSER (self));
+ }
+}
+
+gboolean gtk_app_chooser_widget_get_show_other (GtkAppChooserWidget *self)
+{
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self), FALSE);
+
+ return self->priv->show_other;
+}
+
+void
+gtk_app_chooser_widget_set_show_all (GtkAppChooserWidget *self,
+ gboolean setting)
+{
+ g_return_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self));
+
+ if (self->priv->show_all != setting)
+ {
+ self->priv->show_all = setting;
+
+ g_object_notify (G_OBJECT (self), "show-all");
+
+ gtk_app_chooser_refresh (GTK_APP_CHOOSER (self));
+ }
+}
+
+gboolean
+gtk_app_chooser_widget_get_show_all (GtkAppChooserWidget *self)
+{
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self), FALSE);
+
+ return self->priv->show_all;
+}
+
+void
+gtk_app_chooser_widget_set_default_text (GtkAppChooserWidget *self,
+ const gchar *text)
+{
+ g_return_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self));
+
+ if (g_strcmp0 (text, self->priv->default_text) != 0)
+ {
+ g_free (self->priv->default_text);
+ self->priv->default_text = g_strdup (text);
+
+ g_object_notify (G_OBJECT (self), "default-text");
+
+ gtk_app_chooser_refresh (GTK_APP_CHOOSER (self));
+ }
+}
+
+const gchar *
+gtk_app_chooser_widget_get_default_text (GtkAppChooserWidget *self)
+{
+ g_return_val_if_fail (GTK_IS_APP_CHOOSER_WIDGET (self), NULL);
+
+ return self->priv->default_text;
+}
--- /dev/null
+/*
+ * gtkappchooserwidget.h: an app-chooser widget
+ *
+ * Copyright (C) 2004 Novell, Inc.
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Dave Camp <dave@novell.com>
+ * Alexander Larsson <alexl@redhat.com>
+ * Cosimo Cecchi <ccecchi@redhat.com>
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_APP_CHOOSER_WIDGET_H__
+#define __GTK_APP_CHOOSER_WIDGET_H__
+
+#include <gtk/gtkbox.h>
+#include <gio/gio.h>
+
+#define GTK_TYPE_APP_CHOOSER_WIDGET\
+ (gtk_app_chooser_widget_get_type ())
+#define GTK_APP_CHOOSER_WIDGET(obj)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_APP_CHOOSER_WIDGET, GtkAppChooserWidget))
+#define GTK_APP_CHOOSER_WIDGET_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_APP_CHOOSER_WIDGET, GtkAppChooserWidgetClass))
+#define GTK_IS_APP_CHOOSER_WIDGET(obj)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_APP_CHOOSER_WIDGET))
+#define GTK_IS_APP_CHOOSER_WIDGET_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_APP_CHOOSER_WIDGET))
+#define GTK_APP_CHOOSER_WIDGET_GET_CLASS(obj)\
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_APP_CHOOSER_WIDGET, GtkAppChooserWidgetClass))
+
+typedef struct _GtkAppChooserWidget GtkAppChooserWidget;
+typedef struct _GtkAppChooserWidgetClass GtkAppChooserWidgetClass;
+typedef struct _GtkAppChooserWidgetPrivate GtkAppChooserWidgetPrivate;
+
+struct _GtkAppChooserWidget {
+ GtkBox parent;
+
+ /*< private >*/
+ GtkAppChooserWidgetPrivate *priv;
+};
+
+struct _GtkAppChooserWidgetClass {
+ GtkBoxClass parent_class;
+
+ void (* application_selected) (GtkAppChooserWidget *self,
+ GAppInfo *app_info);
+
+ void (* application_activated) (GtkAppChooserWidget *self,
+ GAppInfo *app_info);
+
+ /* padding for future class expansion */
+ gpointer padding[16];
+};
+
+typedef enum {
+ GTK_APP_CHOOSER_WIDGET_SHOW_RECOMMENDED = 1 << 0,
+ GTK_APP_CHOOSER_WIDGET_SHOW_FALLBACK = 1 << 1,
+ GTK_APP_CHOOSER_WIDGET_SHOW_OTHER = 1 << 2,
+ GTK_APP_CHOOSER_WIDGET_SHOW_ALL = 1 << 3,
+} GtkAppChooserWidgetShowFlags;
+
+GType gtk_app_chooser_widget_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gtk_app_chooser_widget_new (const gchar *content_type);
+
+void gtk_app_chooser_widget_set_show_default (GtkAppChooserWidget *self,
+ gboolean setting);
+gboolean gtk_app_chooser_widget_get_show_default (GtkAppChooserWidget *self);
+
+void gtk_app_chooser_widget_set_show_recommended (GtkAppChooserWidget *self,
+ gboolean setting);
+gboolean gtk_app_chooser_widget_get_show_recommended (GtkAppChooserWidget *self);
+
+void gtk_app_chooser_widget_set_show_fallback (GtkAppChooserWidget *self,
+ gboolean setting);
+gboolean gtk_app_chooser_widget_get_show_fallback (GtkAppChooserWidget *self);
+
+void gtk_app_chooser_widget_set_show_other (GtkAppChooserWidget *self,
+ gboolean setting);
+gboolean gtk_app_chooser_widget_get_show_other (GtkAppChooserWidget *self);
+
+void gtk_app_chooser_widget_set_show_all (GtkAppChooserWidget *self,
+ gboolean show_all);
+gboolean gtk_app_chooser_widget_get_show_all (GtkAppChooserWidget *self);
+
+void gtk_app_chooser_widget_set_default_text (GtkAppChooserWidget *self,
+ const gchar *text);
+const gchar * gtk_app_chooser_widget_get_default_text (GtkAppChooserWidget *self);
+
+#endif /* __GTK_APP_CHOOSER_WIDGET_H__ */
+++ /dev/null
-/*
- * gtkopenwith.c: open-with interface
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#include <config.h>
-
-#include "gtkopenwith.h"
-
-#include "gtkintl.h"
-#include "gtkopenwithprivate.h"
-#include "gtkwidget.h"
-
-#include <glib.h>
-
-G_DEFINE_INTERFACE (GtkOpenWith, gtk_open_with, GTK_TYPE_WIDGET);
-
-static void
-gtk_open_with_default_init (GtkOpenWithIface *iface)
-{
- GParamSpec *pspec;
-
- pspec = g_param_spec_string ("content-type",
- P_("Content type"),
- P_("The content type used by the open with object"),
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- g_object_interface_install_property (iface, pspec);
-}
-
-gchar *
-gtk_open_with_get_content_type (GtkOpenWith *self)
-{
- gchar *retval = NULL;
-
- g_return_val_if_fail (GTK_IS_OPEN_WITH (self), NULL);
-
- g_object_get (self,
- "content-type", &retval,
- NULL);
-
- return retval;
-}
-
-GAppInfo *
-gtk_open_with_get_app_info (GtkOpenWith *self)
-{
- return GTK_OPEN_WITH_GET_IFACE (self)->get_app_info (self);
-}
-
-void
-gtk_open_with_refresh (GtkOpenWith *self)
-{
- GTK_OPEN_WITH_GET_IFACE (self)->refresh (self);
-}
+++ /dev/null
-/*
- * gtkopenwith.h: open-with interface
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#ifndef __GTK_OPEN_WITH_H__
-#define __GTK_OPEN_WITH_H__
-
-#include <glib.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_OPEN_WITH\
- (gtk_open_with_get_type ())
-#define GTK_OPEN_WITH(obj)\
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_OPEN_WITH, GtkOpenWith))
-#define GTK_IS_OPEN_WITH(obj)\
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_OPEN_WITH))
-
-typedef struct _GtkOpenWith GtkOpenWith;
-
-GType gtk_open_with_get_type () G_GNUC_CONST;
-
-GAppInfo * gtk_open_with_get_app_info (GtkOpenWith *self);
-gchar * gtk_open_with_get_content_type (GtkOpenWith *self);
-void gtk_open_with_refresh (GtkOpenWith *self);
-
-G_END_DECLS
-
-#endif /* __GTK_OPEN_WITH_H__ */
-
+++ /dev/null
-/*
- * gtkopenwithdialog.c: an open-with dialog
- *
- * Copyright (C) 2004 Novell, Inc.
- * Copyright (C) 2007, 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Dave Camp <dave@novell.com>
- * Alexander Larsson <alexl@redhat.com>
- * Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#include <config.h>
-
-#include "gtkopenwithdialog.h"
-
-#include "gtkintl.h"
-#include "gtkopenwith.h"
-#include "gtkopenwithonline.h"
-#include "gtkopenwithprivate.h"
-
-#include <string.h>
-#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-#include <gio/gio.h>
-
-#define sure_string(s) ((const char *) ((s) != NULL ? (s) : ""))
-
-struct _GtkOpenWithDialogPrivate {
- char *content_type;
- GFile *gfile;
-
- GtkWidget *label;
- GtkWidget *button;
- GtkWidget *online_button;
-
- GtkWidget *open_label;
-
- GtkWidget *open_with_widget;
- GtkWidget *show_more_button;
-
- gboolean show_more_clicked;
-};
-
-enum {
- PROP_GFILE = 1,
- PROP_CONTENT_TYPE,
- N_PROPERTIES
-};
-
-static void gtk_open_with_dialog_iface_init (GtkOpenWithIface *iface);
-G_DEFINE_TYPE_WITH_CODE (GtkOpenWithDialog, gtk_open_with_dialog, GTK_TYPE_DIALOG,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_OPEN_WITH,
- gtk_open_with_dialog_iface_init));
-
-static void
-show_error_dialog (const gchar *primary,
- const gchar *secondary,
- GtkWindow *parent)
-{
- GtkWidget *message_dialog;
-
- message_dialog = gtk_message_dialog_new (parent, 0,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- NULL);
- g_object_set (message_dialog,
- "text", primary,
- "secondary-text", secondary,
- NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (message_dialog), GTK_RESPONSE_OK);
-
- gtk_widget_show (message_dialog);
-
- g_signal_connect (message_dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
-}
-
-static void
-search_for_mimetype_ready_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
-{
- GtkOpenWithOnline *online = GTK_OPEN_WITH_ONLINE (source);
- GtkOpenWithDialog *self = user_data;
- GError *error = NULL;
-
- gtk_open_with_online_search_for_mimetype_finish (online, res, &error);
-
- if (error != NULL)
- {
- show_error_dialog (_("Failed to look for applications online"),
- error->message, GTK_WINDOW (self));
- g_error_free (error);
- }
- else
- {
- gtk_open_with_refresh (GTK_OPEN_WITH (self->priv->open_with_widget));
- }
-
- g_object_unref (online);
-}
-
-static void
-online_button_clicked_cb (GtkButton *b,
- gpointer user_data)
-{
- GtkOpenWithOnline *online;
- GtkOpenWithDialog *self = user_data;
-
- online = gtk_open_with_online_get_default ();
-
- gtk_open_with_online_search_for_mimetype_async (online,
- self->priv->content_type,
- GTK_WINDOW (self),
- search_for_mimetype_ready_cb,
- self);
-}
-
-/* An application is valid if:
- *
- * 1) The file exists
- * 2) The user has permissions to run the file
- */
-static gboolean
-check_application (GtkOpenWithDialog *self,
- GAppInfo **app_out)
-{
- const char *command;
- char *path = NULL;
- char **argv = NULL;
- int argc;
- GError *error = NULL;
- gint retval = TRUE;
- GAppInfo *info;
-
- command = NULL;
-
- info = gtk_open_with_get_app_info (GTK_OPEN_WITH (self->priv->open_with_widget));
- command = g_app_info_get_executable (info);
-
- g_shell_parse_argv (command, &argc, &argv, &error);
-
- if (error)
- {
- show_error_dialog (_("Could not run application"),
- error->message,
- GTK_WINDOW (self));
- g_error_free (error);
- retval = FALSE;
- goto cleanup;
- }
-
- path = g_find_program_in_path (argv[0]);
- if (!path)
- {
- char *error_message;
-
- error_message = g_strdup_printf (_("Could not find '%s'"),
- argv[0]);
-
- show_error_dialog (_("Could not find application"),
- error_message,
- GTK_WINDOW (self));
- g_free (error_message);
- retval = FALSE;
- goto cleanup;
- }
-
- *app_out = info;
-
- cleanup:
- g_strfreev (argv);
- g_free (path);
-
- return retval;
-}
-
-static void
-widget_application_selected_cb (GtkOpenWithWidget *widget,
- GAppInfo *app_info,
- gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
-
- gtk_widget_set_sensitive (self->priv->button, TRUE);
-}
-
-static void
-widget_application_activated_cb (GtkOpenWithWidget *widget,
- GAppInfo *app_info,
- gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
-
- gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
-}
-
-static char *
-get_extension (const char *basename)
-{
- char *p;
-
- p = strrchr (basename, '.');
-
- if (p && *(p + 1) != '\0')
- return g_strdup (p + 1);
-
- return NULL;
-}
-
-static void
-set_dialog_properties (GtkOpenWithDialog *self)
-{
- char *label, *name, *extension, *description, *default_text, *string;
- PangoFontDescription *font_desc;
-
- name = NULL;
- extension = NULL;
- label = NULL;
- description = NULL;
-
- if (self->priv->gfile != NULL)
- {
- name = g_file_get_basename (self->priv->gfile);
- extension = get_extension (name);
- }
-
- description = g_content_type_get_description (self->priv->content_type);
- gtk_window_set_title (GTK_WINDOW (self), "");
-
- if (name != NULL)
- {
- /* Translators: %s is a filename */
- label = g_strdup_printf (_("Select an application to open \"%s\""), name);
- string = g_strdup_printf (_("No applications available to open \"%s\""),
- name);
- }
- else
- {
- /* Translators: %s is a file type description */
- label = g_strdup_printf (_("Select an application for \"%s\" files"),
- g_content_type_is_unknown (self->priv->content_type) ?
- self->priv->content_type : description);
- string = g_strdup_printf (_("No applications available to open \"%s\" files"),
- g_content_type_is_unknown (self->priv->content_type) ?
- self->priv->content_type : description);
- }
-
- font_desc = pango_font_description_new ();
- pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
- gtk_widget_modify_font (self->priv->label, font_desc);
- pango_font_description_free (font_desc);
-
- gtk_label_set_markup (GTK_LABEL (self->priv->label), label);
-
- default_text = g_strdup_printf ("<big><b>%s</b></big>\n%s",
- string,
- _("Click \"Show other applications\", for more options, or "
- "\"Find applications online\" to install a new application"));
-
- gtk_open_with_widget_set_default_text (GTK_OPEN_WITH_WIDGET (self->priv->open_with_widget),
- default_text);
-
- g_free (label);
- g_free (name);
- g_free (extension);
- g_free (description);
- g_free (string);
- g_free (default_text);
-}
-
-static void
-show_more_button_clicked_cb (GtkButton *button,
- gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
-
- g_object_set (self->priv->open_with_widget,
- "show-recommended", TRUE,
- "show-fallback", TRUE,
- "show-other", TRUE,
- NULL);
-
- gtk_widget_hide (self->priv->show_more_button);
- self->priv->show_more_clicked = TRUE;
-}
-
-static void
-widget_notify_for_button_cb (GObject *source,
- GParamSpec *pspec,
- gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
- GtkOpenWithWidget *widget = GTK_OPEN_WITH_WIDGET (source);
- gboolean should_hide;
-
- should_hide = gtk_open_with_widget_get_show_all (widget) ||
- self->priv->show_more_clicked;
-
- if (should_hide)
- gtk_widget_hide (self->priv->show_more_button);
-}
-
-static void
-build_dialog_ui (GtkOpenWithDialog *self)
-{
- GtkWidget *vbox;
- GtkWidget *vbox2;
- GtkWidget *label;
- GtkWidget *action_area, *button, *w;
-
- gtk_container_set_border_width (GTK_CONTAINER (self), 5);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), vbox, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
- gtk_widget_show (vbox2);
-
- self->priv->label = gtk_label_new ("");
- gtk_misc_set_alignment (GTK_MISC (self->priv->label), 0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (self->priv->label), TRUE);
- gtk_box_pack_start (GTK_BOX (vbox2), self->priv->label,
- FALSE, FALSE, 0);
- gtk_widget_show (self->priv->label);
-
- self->priv->open_with_widget =
- gtk_open_with_widget_new (self->priv->content_type);
- gtk_box_pack_start (GTK_BOX (vbox2), self->priv->open_with_widget, TRUE, TRUE, 0);
- gtk_widget_show (self->priv->open_with_widget);
-
- g_signal_connect (self->priv->open_with_widget, "application-selected",
- G_CALLBACK (widget_application_selected_cb), self);
- g_signal_connect (self->priv->open_with_widget, "application-activated",
- G_CALLBACK (widget_application_activated_cb), self);
- g_signal_connect (self->priv->open_with_widget, "notify::show-all",
- G_CALLBACK (widget_notify_for_button_cb), self);
-
- button = gtk_button_new_with_label (_("Show other applications"));
- self->priv->show_more_button = button;
- w = gtk_image_new_from_stock (GTK_STOCK_ADD,
- GTK_ICON_SIZE_BUTTON);
- gtk_button_set_image (GTK_BUTTON (button), w);
- gtk_box_pack_start (GTK_BOX (self->priv->open_with_widget), button, FALSE, FALSE, 6);
- gtk_widget_show_all (button);
-
- g_signal_connect (button, "clicked",
- G_CALLBACK (show_more_button_clicked_cb), self);
-
- gtk_dialog_add_button (GTK_DIALOG (self),
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
-
- /* Create a custom stock icon */
- self->priv->button = gtk_button_new ();
-
- label = gtk_label_new_with_mnemonic (_("_Open"));
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (self->priv->button));
- gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
- gtk_widget_show (label);
- self->priv->open_label = label;
-
- gtk_container_add (GTK_CONTAINER (self->priv->button),
- self->priv->open_label);
-
- gtk_widget_show (self->priv->button);
- gtk_widget_set_can_default (self->priv->button, TRUE);
-
- gtk_dialog_add_action_widget (GTK_DIALOG (self),
- self->priv->button, GTK_RESPONSE_OK);
-
- action_area = gtk_dialog_get_action_area (GTK_DIALOG (self));
- self->priv->online_button = gtk_button_new_with_label (_("Find applications online"));
- gtk_box_pack_start (GTK_BOX (action_area), self->priv->online_button,
- FALSE, FALSE, 0);
- gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), self->priv->online_button,
- TRUE);
- gtk_widget_show (self->priv->online_button);
- g_signal_connect (self->priv->online_button, "clicked",
- G_CALLBACK (online_button_clicked_cb), self);
-
- gtk_dialog_set_default_response (GTK_DIALOG (self),
- GTK_RESPONSE_OK);
-}
-
-static void
-set_gfile_and_content_type (GtkOpenWithDialog *self,
- GFile *file)
-{
- GFileInfo *info;
-
- if (file == NULL)
- return;
-
- self->priv->gfile = g_object_ref (file);
-
- info = g_file_query_info (self->priv->gfile,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- 0, NULL, NULL);
- self->priv->content_type = g_strdup (g_file_info_get_content_type (info));
-
- g_object_unref (info);
-}
-
-static GAppInfo *
-gtk_open_with_dialog_get_app_info (GtkOpenWith *object)
-{
- GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
- GAppInfo *app = NULL;
-
- if (!check_application (self, &app))
- return NULL;
-
- return app;
-}
-
-static void
-gtk_open_with_dialog_refresh (GtkOpenWith *object)
-{
- GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
-
- gtk_open_with_refresh (GTK_OPEN_WITH (self->priv->open_with_widget));
-}
-
-static void
-gtk_open_with_dialog_constructed (GObject *object)
-{
- GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
-
- g_assert (self->priv->content_type != NULL ||
- self->priv->gfile != NULL);
-
- if (G_OBJECT_CLASS (gtk_open_with_dialog_parent_class)->constructed != NULL)
- G_OBJECT_CLASS (gtk_open_with_dialog_parent_class)->constructed (object);
-
- build_dialog_ui (self);
- set_dialog_properties (self);
-}
-
-static void
-gtk_open_with_dialog_finalize (GObject *object)
-{
- GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
-
- if (self->priv->gfile)
- g_object_unref (self->priv->gfile);
-
- g_free (self->priv->content_type);
-
- G_OBJECT_CLASS (gtk_open_with_dialog_parent_class)->finalize (object);
-}
-
-static void
-gtk_open_with_dialog_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
-
- switch (property_id)
- {
- case PROP_GFILE:
- set_gfile_and_content_type (self, g_value_get_object (value));
- break;
- case PROP_CONTENT_TYPE:
- /* don't try to override a value previously set with the GFile */
- if (self->priv->content_type == NULL)
- self->priv->content_type = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-gtk_open_with_dialog_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
-
- switch (property_id)
- {
- case PROP_GFILE:
- if (self->priv->gfile != NULL)
- g_value_set_object (value, self->priv->gfile);
- break;
- case PROP_CONTENT_TYPE:
- g_value_set_string (value, self->priv->content_type);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-gtk_open_with_dialog_iface_init (GtkOpenWithIface *iface)
-{
- iface->get_app_info = gtk_open_with_dialog_get_app_info;
- iface->refresh = gtk_open_with_dialog_refresh;
-}
-
-static void
-gtk_open_with_dialog_class_init (GtkOpenWithDialogClass *klass)
-{
- GObjectClass *gobject_class;
- GParamSpec *pspec;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = gtk_open_with_dialog_finalize;
- gobject_class->set_property = gtk_open_with_dialog_set_property;
- gobject_class->get_property = gtk_open_with_dialog_get_property;
- gobject_class->constructed = gtk_open_with_dialog_constructed;
-
- g_object_class_override_property (gobject_class, PROP_CONTENT_TYPE, "content-type");
-
- pspec = g_param_spec_object ("gfile",
- P_("GFile"),
- P_("The GFile used by the open with dialog"),
- G_TYPE_FILE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (gobject_class, PROP_GFILE, pspec);
-
- g_type_class_add_private (klass, sizeof (GtkOpenWithDialogPrivate));
-}
-
-static void
-gtk_open_with_dialog_init (GtkOpenWithDialog *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_OPEN_WITH_DIALOG,
- GtkOpenWithDialogPrivate);
-}
-
-static void
-set_parent_and_flags (GtkWidget *dialog,
- GtkWindow *parent,
- GtkDialogFlags flags)
-{
- if (parent != NULL)
- gtk_window_set_transient_for (GTK_WINDOW (dialog),
- parent);
-
- if (flags & GTK_DIALOG_MODAL)
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-
- if (flags & GTK_DIALOG_DESTROY_WITH_PARENT)
- gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
-}
-
-/**
- * gtk_open_with_dialog_new:
- * @parent: (allow-none): a #GtkWindow, or %NULL
- * @flags: flags for this dialog
- * @file: a #GFile
- *
- * Creates a new #GtkOpenWithDialog for the provided #GFile, to allow
- * the user to select an application for it.
- *
- * Returns: a newly created #GtkOpenWithDialog
- *
- * Since: 3.0
- **/
-GtkWidget *
-gtk_open_with_dialog_new (GtkWindow *parent,
- GtkDialogFlags flags,
- GFile *file)
-{
- GtkWidget *retval;
-
- g_return_val_if_fail (G_IS_FILE (file), NULL);
-
- retval = g_object_new (GTK_TYPE_OPEN_WITH_DIALOG,
- "gfile", file,
- NULL);
-
- set_parent_and_flags (retval, parent, flags);
-
- return retval;
-}
-
-/**
- * gtk_open_with_dialog_new_for_content_type:
- * @parent: (allow-none): a #GtkWindow, or %NULL
- * @flags: flags for this dialog
- * @content_type: a content type string
- *
- * Creates a new #GtkOpenWithDialog for the provided content type, to allow
- * the user to select an application for it.
- *
- * Returns: a newly created #GtkOpenWithDialog
- *
- * Since: 3.0
- **/
-GtkWidget *
-gtk_open_with_dialog_new_for_content_type (GtkWindow *parent,
- GtkDialogFlags flags,
- const gchar *content_type)
-{
- GtkWidget *retval;
-
- g_return_val_if_fail (content_type != NULL, NULL);
-
- retval = g_object_new (GTK_TYPE_OPEN_WITH_DIALOG,
- "content-type", content_type,
- NULL);
-
- set_parent_and_flags (retval, parent, flags);
-
- return retval;
-}
-
-GtkWidget *
-gtk_open_with_dialog_get_widget (GtkOpenWithDialog *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_DIALOG (self), NULL);
-
- return self->priv->open_with_widget;
-}
+++ /dev/null
-/*
- * gtkopenwithdialog.h: an open-with dialog
- *
- * Copyright (C) 2004 Novell, Inc.
- * Copyright (C) 2007, 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Dave Camp <dave@novell.com>
- * Alexander Larsson <alexl@redhat.com>
- * Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#ifndef __GTK_OPEN_WITH_DIALOG_H__
-#define __GTK_OPEN_WITH_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-#include <gio/gio.h>
-
-#define GTK_TYPE_OPEN_WITH_DIALOG\
- (gtk_open_with_dialog_get_type ())
-#define GTK_OPEN_WITH_DIALOG(obj)\
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_OPEN_WITH_DIALOG, GtkOpenWithDialog))
-#define GTK_OPEN_WITH_DIALOG_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_OPEN_WITH_DIALOG, GtkOpenWithDialogClass))
-#define GTK_IS_OPEN_WITH_DIALOG(obj)\
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_OPEN_WITH_DIALOG))
-#define GTK_IS_OPEN_WITH_DIALOG_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_OPEN_WITH_DIALOG))
-#define GTK_OPEN_WITH_DIALOG_GET_CLASS(obj)\
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_OPEN_WITH_DIALOG, GtkOpenWithDialogClass))
-
-typedef struct _GtkOpenWithDialog GtkOpenWithDialog;
-typedef struct _GtkOpenWithDialogClass GtkOpenWithDialogClass;
-typedef struct _GtkOpenWithDialogPrivate GtkOpenWithDialogPrivate;
-
-struct _GtkOpenWithDialog {
- GtkDialog parent;
-
- /*< private >*/
- GtkOpenWithDialogPrivate *priv;
-};
-
-struct _GtkOpenWithDialogClass {
- GtkDialogClass parent_class;
-
- /* padding for future class expansion */
- gpointer padding[16];
-};
-
-GType gtk_open_with_dialog_get_type (void) G_GNUC_CONST;
-
-GtkWidget * gtk_open_with_dialog_new (GtkWindow *parent,
- GtkDialogFlags flags,
- GFile *file);
-GtkWidget * gtk_open_with_dialog_new_for_content_type (GtkWindow *parent,
- GtkDialogFlags flags,
- const gchar *content_type);
-
-GtkWidget * gtk_open_with_dialog_get_widget (GtkOpenWithDialog *self);
-
-#endif /* __GTK_OPEN_WITH_DIALOG_H__ */
+++ /dev/null
-/*
- * gtkopenwithmodule.c: an extension point for online integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#include <config.h>
-
-#include "gtkopenwithmodule.h"
-
-#include <gio/gio.h>
-
-#include "gtkopenwithonline.h"
-#include "gtkopenwithonlinedummy.h"
-
-#ifdef ENABLE_PACKAGEKIT
-#include "gtkopenwithonlinepk.h"
-#endif
-
-G_LOCK_DEFINE_STATIC (registered_ep);
-
-void
-_gtk_open_with_module_ensure (void)
-{
- static gboolean registered_ep = FALSE;
- GIOExtensionPoint *ep;
-
- G_LOCK (registered_ep);
-
- if (!registered_ep)
- {
- registered_ep = TRUE;
-
- ep = g_io_extension_point_register ("gtkopenwith-online");
- g_io_extension_point_set_required_type (ep, GTK_TYPE_OPEN_WITH_ONLINE);
-
- _gtk_open_with_online_dummy_get_type ();
-
-#ifdef ENABLE_PACKAGEKIT
- _gtk_open_with_online_pk_get_type ();
-#endif
- }
-
- G_UNLOCK (registered_ep);
-}
+++ /dev/null
-/*
- * gtkopenwithmodule.h: an extension point for PackageKit integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#ifndef __GTK_OPEN_WITH_MODULE_H__
-#define __GTK_OPEN_WITH_MODULE_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-void _gtk_open_with_module_ensure (void);
-
-G_END_DECLS
-
-#endif /* __GTK_OPEN_WITH_MODULE_H__ */
+++ /dev/null
-/*
- * gtkopenwithonline.h: an extension point for online integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#include <config.h>
-
-#include "gtkopenwithonline.h"
-
-#include "gtkopenwithonlinedummy.h"
-#include "gtkopenwithmodule.h"
-
-#include <gio/gio.h>
-
-G_DEFINE_INTERFACE (GtkOpenWithOnline, gtk_open_with_online, G_TYPE_OBJECT);
-
-static void
-gtk_open_with_online_default_init (GtkOpenWithOnlineInterface *iface)
-{
- /* do nothing */
-}
-
-GtkOpenWithOnline *
-gtk_open_with_online_get_default (void)
-{
- GIOExtensionPoint *ep;
- GIOExtension *extension;
- GList *extensions;
- GtkOpenWithOnline *retval;
-
- _gtk_open_with_module_ensure ();
-
- ep = g_io_extension_point_lookup ("gtkopenwith-online");
- extensions = g_io_extension_point_get_extensions (ep);
-
- if (extensions != NULL)
- {
- /* pick the first */
- extension = extensions->data;
- retval = g_object_new (g_io_extension_get_type (extension),
- NULL);
- }
- else
- {
- retval = g_object_new (GTK_TYPE_OPEN_WITH_ONLINE_DUMMY,
- NULL);
- }
-
- return retval;
-}
-
-void
-gtk_open_with_online_search_for_mimetype_async (GtkOpenWithOnline *self,
- const gchar *content_type,
- GtkWindow *parent,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GtkOpenWithOnlineInterface *iface;
-
- g_return_if_fail (GTK_IS_OPEN_WITH_ONLINE (self));
-
- iface = GTK_OPEN_WITH_ONLINE_GET_IFACE (self);
-
- (* iface->search_for_mimetype_async) (self, content_type, parent, callback, user_data);
-}
-
-gboolean
-gtk_open_with_online_search_for_mimetype_finish (GtkOpenWithOnline *self,
- GAsyncResult *res,
- GError **error)
-{
- GtkOpenWithOnlineInterface *iface;
-
- g_return_val_if_fail (GTK_IS_OPEN_WITH_ONLINE (self), FALSE);
-
- iface = GTK_OPEN_WITH_ONLINE_GET_IFACE (self);
-
- return ((* iface->search_for_mimetype_finish) (self, res, error));
-}
+++ /dev/null
-/*
- * gtkopenwithonline.h: an extension point for online integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#ifndef __GTK_OPEN_WITH_ONLINE_H__
-#define __GTK_OPEN_WITH_ONLINE_H__
-
-#include <glib.h>
-
-#include <gtk/gtkwindow.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_OPEN_WITH_ONLINE\
- (gtk_open_with_online_get_type ())
-#define GTK_OPEN_WITH_ONLINE(o)\
- (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_OPEN_WITH_ONLINE, GtkOpenWithOnline))
-#define GTK_IS_OPEN_WITH_ONLINE(o)\
- (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_OPEN_WITH_ONLINE))
-#define GTK_OPEN_WITH_ONLINE_GET_IFACE(obj)\
- (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_OPEN_WITH_ONLINE, GtkOpenWithOnlineInterface))
-
-typedef struct _GtkOpenWithOnline GtkOpenWithOnline;
-typedef struct _GtkOpenWithOnlineInterface GtkOpenWithOnlineInterface;
-
-struct _GtkOpenWithOnlineInterface {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*search_for_mimetype_async) (GtkOpenWithOnline *self,
- const gchar *content_type,
- GtkWindow *parent,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
- gboolean (*search_for_mimetype_finish) (GtkOpenWithOnline *self,
- GAsyncResult *res,
- GError **error);
-};
-
-GType gtk_open_with_online_get_type (void) G_GNUC_CONST;
-void gtk_open_with_online_search_for_mimetype_async (GtkOpenWithOnline *self,
- const gchar *content_type,
- GtkWindow *parent,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean gtk_open_with_online_search_for_mimetype_finish (GtkOpenWithOnline *self,
- GAsyncResult *res,
- GError **error);
-
-GtkOpenWithOnline * gtk_open_with_online_get_default (void);
-
-#endif /* __GTK_OPEN_WITH_ONLINE_H__ */
+++ /dev/null
-/*
- * gtkopenwithonlinedummy.c: an extension point for online integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#include <config.h>
-
-#include "gtkopenwithonlinedummy.h"
-
-#include "gtkintl.h"
-#include "gtkopenwithonline.h"
-
-#include <gio/gio.h>
-
-#define gtk_open_with_online_dummy_get_type _gtk_open_with_online_dummy_get_type
-static void open_with_online_iface_init (GtkOpenWithOnlineInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GtkOpenWithOnlineDummy, gtk_open_with_online_dummy,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_OPEN_WITH_ONLINE,
- open_with_online_iface_init)
- g_io_extension_point_implement ("gtkopenwith-online",
- g_define_type_id,
- "dummy", 0));
-
-static void
-gtk_open_with_online_dummy_class_init (GtkOpenWithOnlineDummyClass *klass)
-{
- /* do nothing */
-}
-
-static void
-gtk_open_with_online_dummy_init (GtkOpenWithOnlineDummy *self)
-{
- /* do nothing */
-}
-
-static gboolean
-dummy_search_mime_finish (GtkOpenWithOnline *obj,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-
- return !g_simple_async_result_propagate_error (simple, error);
-}
-
-static void
-dummy_search_mime_async (GtkOpenWithOnline *obj,
- const gchar *content_type,
- GtkWindow *parent,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_simple_async_report_error_in_idle (G_OBJECT (obj),
- callback, user_data,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "%s",
- _("Operation not supported"));
-}
-
-static void
-open_with_online_iface_init (GtkOpenWithOnlineInterface *iface)
-{
- iface->search_for_mimetype_async = dummy_search_mime_async;
- iface->search_for_mimetype_finish = dummy_search_mime_finish;
-}
+++ /dev/null
-/*
- * gtkopenwithonlinedummy.h: an extension point for online integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#ifndef __GTK_OPEN_WITH_ONLINE_DUMMY_H__
-#define __GTK_OPEN_WITH_ONLINE_DUMMY_H__
-
-#include <gtk/gtkopenwithonline.h>
-#include <glib.h>
-
-#define GTK_TYPE_OPEN_WITH_ONLINE_DUMMY\
- (_gtk_open_with_online_dummy_get_type ())
-#define GTK_OPEN_WITH_ONLINE_DUMMY(obj)\
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_OPEN_WITH_ONLINE_DUMMY, GtkOpenWithOnlineDummy))
-#define GTK_OPEN_WITH_ONLINE_DUMMY_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_OPEN_WITH_ONLINE_DUMMY, GtkOpenWithOnlineDummyClass))
-#define GTK_IS_OPEN_WITH_ONLINE_DUMMY(obj)\
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_OPEN_WITH_ONLINE_DUMMY))
-#define GTK_IS_OPEN_WITH_ONLINE_DUMMY_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_OPEN_WITH_ONLINE_DUMMY))
-#define GTK_OPEN_WITH_ONLINE_DUMMY_GET_CLASS(obj)\
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_OPEN_WITH_ONLINE_DUMMY, GtkOpenWithOnlineDummyClass))
-
-typedef struct _GtkOpenWithOnlineDummy GtkOpenWithOnlineDummy;
-typedef struct _GtkOpenWithOnlineDummyClass GtkOpenWithOnlineDummyClass;
-typedef struct _GtkOpenWithOnlineDummyPrivate GtkOpenWithOnlineDummyPrivate;
-
-struct _GtkOpenWithOnlineDummy {
- GObject parent;
-};
-
-struct _GtkOpenWithOnlineDummyClass {
- GObjectClass parent_class;
-
- GtkOpenWithOnlineDummy *priv;
-};
-
-GType _gtk_open_with_online_dummy_get_type (void);
-
-#endif /* __GTK_OPEN_WITH_ONLINE_DUMMY_H__ */
+++ /dev/null
-/*
- * gtkopenwithonlinepk.c: packagekit module for open with
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#include <config.h>
-
-#include "gtkopenwithonlinepk.h"
-
-#include "gtkopenwithonline.h"
-#include "x11/gdkx.h"
-
-#include <gio/gio.h>
-
-#define gtk_open_with_online_pk_get_type _gtk_open_with_online_pk_get_type
-static void open_with_online_iface_init (GtkOpenWithOnlineInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GtkOpenWithOnlinePk, gtk_open_with_online_pk,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_OPEN_WITH_ONLINE,
- open_with_online_iface_init)
- g_io_extension_point_implement ("gtkopenwith-online",
- g_define_type_id,
- "packagekit", 10));
-
-struct _GtkOpenWithOnlinePkPrivate {
- GSimpleAsyncResult *result;
- GtkWindow *parent;
- gchar *content_type;
-};
-
-static void
-gtk_open_with_online_pk_finalize (GObject *obj)
-{
- GtkOpenWithOnlinePk *self = GTK_OPEN_WITH_ONLINE_PK (obj);
-
- g_free (self->priv->content_type);
- g_clear_object (&self->priv->result);
-
- G_OBJECT_CLASS (gtk_open_with_online_pk_parent_class)->finalize (obj);
-}
-
-static void
-gtk_open_with_online_pk_class_init (GtkOpenWithOnlinePkClass *klass)
-{
- GObjectClass *oclass = G_OBJECT_CLASS (klass);
-
- oclass->finalize = gtk_open_with_online_pk_finalize;
-
- g_type_class_add_private (klass, sizeof (GtkOpenWithOnlinePkPrivate));
-}
-
-static void
-gtk_open_with_online_pk_init (GtkOpenWithOnlinePk *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_OPEN_WITH_ONLINE_PK,
- GtkOpenWithOnlinePkPrivate);
-}
-
-static gboolean
-pk_search_mime_finish (GtkOpenWithOnline *obj,
- GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-
- return !g_simple_async_result_propagate_error (simple, error);
-}
-
-static void
-install_mime_types_ready_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
-{
- GtkOpenWithOnlinePk *self = user_data;
- GDBusProxy *proxy = G_DBUS_PROXY (source);
- GError *error = NULL;
- GVariant *variant;
-
- variant = g_dbus_proxy_call_finish (proxy, res, &error);
-
- if (variant == NULL) {
- /* don't show errors if the user cancelled the installation explicitely
- * or if PK wasn't able to find any apps
- */
- if (g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.Cancelled") != 0 &&
- g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.NoPackagesFound") != 0)
- g_simple_async_result_set_from_error (self->priv->result, error);
-
- g_error_free (error);
- }
-
- g_simple_async_result_complete (self->priv->result);
-}
-
-static void
-pk_proxy_appeared_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
-{
- GtkOpenWithOnlinePk *self = user_data;
- GDBusProxy *proxy;
- GError *error = NULL;
- guint xid = 0;
- GdkWindow *window;
- const gchar *mime_types[2];
-
- proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
-
- if (error != NULL) {
- g_simple_async_result_set_from_error (self->priv->result, error);
- g_error_free (error);
-
- g_simple_async_result_complete (self->priv->result);
-
- return;
- }
-
- window = gtk_widget_get_window (GTK_WIDGET (self->priv->parent));
- xid = GDK_WINDOW_XID (window);
-
- mime_types[0] = self->priv->content_type;
- mime_types[1] = NULL;
-
- g_dbus_proxy_call (proxy,
- "InstallMimeTypes",
- g_variant_new ("(u^ass)",
- xid,
- mime_types,
- "hide-confirm-search"),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT, /* no timeout */
- NULL,
- install_mime_types_ready_cb,
- self);
-}
-
-static void
-pk_search_mime_async (GtkOpenWithOnline *obj,
- const gchar *content_type,
- GtkWindow *parent,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GtkOpenWithOnlinePk *self = GTK_OPEN_WITH_ONLINE_PK (obj);
-
- self->priv->result = g_simple_async_result_new (G_OBJECT (self),
- callback, user_data,
- gtk_open_with_online_search_for_mimetype_async);
- self->priv->parent = parent;
- self->priv->content_type = g_strdup (content_type);
-
- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.freedesktop.PackageKit",
- "/org/freedesktop/PackageKit",
- "org.freedesktop.PackageKit.Modify",
- NULL,
- pk_proxy_appeared_cb,
- self);
-}
-
-static void
-open_with_online_iface_init (GtkOpenWithOnlineInterface *iface)
-{
- iface->search_for_mimetype_async = pk_search_mime_async;
- iface->search_for_mimetype_finish = pk_search_mime_finish;
-}
+++ /dev/null
-/*
- * gtkopenwithonlinepk.h: an extension point for online integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#ifndef __GTK_OPEN_WITH_ONLINE_PK_H__
-#define __GTK_OPEN_WITH_ONLINE_PK_H__
-
-#include <gtk/gtkopenwithonline.h>
-#include <glib.h>
-
-#define GTK_TYPE_OPEN_WITH_ONLINE_PK\
- (_gtk_open_with_online_pk_get_type ())
-#define GTK_OPEN_WITH_ONLINE_PK(obj)\
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_OPEN_WITH_ONLINE_PK, GtkOpenWithOnlinePk))
-#define GTK_OPEN_WITH_ONLINE_PK_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_OPEN_WITH_ONLINE_PK, GtkOpenWithOnlinePkClass))
-#define GTK_IS_OPEN_WITH_ONLINE_PK(obj)\
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_OPEN_WITH_ONLINE_PK))
-#define GTK_IS_OPEN_WITH_ONLINE_PK_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_OPEN_WITH_ONLINE_PK))
-#define GTK_OPEN_WITH_ONLINE_PK_GET_CLASS(obj)\
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_OPEN_WITH_ONLINE_PK, GtkOpenWithOnlinePkClass))
-
-typedef struct _GtkOpenWithOnlinePk GtkOpenWithOnlinePk;
-typedef struct _GtkOpenWithOnlinePkClass GtkOpenWithOnlinePkClass;
-typedef struct _GtkOpenWithOnlinePkPrivate GtkOpenWithOnlinePkPrivate;
-
-struct _GtkOpenWithOnlinePk {
- GObject parent;
-
- GtkOpenWithOnlinePkPrivate *priv;
-};
-
-struct _GtkOpenWithOnlinePkClass {
- GObjectClass parent_class;
-};
-
-GType _gtk_open_with_online_pk_get_type (void);
-
-#endif /* __GTK_OPEN_WITH_ONLINE_PK_H__ */
+++ /dev/null
-/*
- * gtkopenwith.c: open-with interface
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#ifndef __GTK_OPEN_WITH_PRIVATE_H__
-#define __GTK_OPEN_WITH_PRIVATE_H__
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#include "gtkopenwithwidget.h"
-
-typedef struct _GtkOpenWithIface GtkOpenWithIface;
-typedef GtkOpenWithIface GtkOpenWithInterface;
-
-#define GTK_OPEN_WITH_GET_IFACE(inst)\
- (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_OPEN_WITH, GtkOpenWithIface))
-
-struct _GtkOpenWithIface {
- GTypeInterface base_iface;
-
- GAppInfo * (* get_app_info) (GtkOpenWith *object);
- void (* refresh) (GtkOpenWith *object);
-};
-
-#endif /* __GTK_OPEN_WITH_PRIVATE_H__ */
+++ /dev/null
-/*
- * gtkopenwithwidget.c: an open-with widget
- *
- * Copyright (C) 2004 Novell, Inc.
- * Copyright (C) 2007, 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Dave Camp <dave@novell.com>
- * Alexander Larsson <alexl@redhat.com>
- * Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#include <config.h>
-
-#include "gtkopenwithwidget.h"
-
-#include "gtkintl.h"
-#include "gtkmarshalers.h"
-#include "gtkopenwith.h"
-#include "gtkopenwithprivate.h"
-
-#include <string.h>
-#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-#include <gio/gio.h>
-
-struct _GtkOpenWithWidgetPrivate {
- GAppInfo *selected_app_info;
-
- gchar *content_type;
- gchar *default_text;
- gboolean show_default;
- gboolean show_recommended;
- gboolean show_fallback;
- gboolean show_other;
- gboolean show_all;
-
- GtkWidget *program_list;
- GtkListStore *program_list_store;
-
- GtkCellRenderer *padding_renderer;
-};
-
-enum {
- COLUMN_APP_INFO,
- COLUMN_GICON,
- COLUMN_NAME,
- COLUMN_DESC,
- COLUMN_EXEC,
- COLUMN_DEFAULT,
- COLUMN_HEADING,
- COLUMN_HEADING_TEXT,
- COLUMN_RECOMMENDED,
- COLUMN_FALLBACK,
- NUM_COLUMNS
-};
-
-
-enum {
- PROP_CONTENT_TYPE = 1,
- PROP_GFILE,
- PROP_SHOW_DEFAULT,
- PROP_SHOW_RECOMMENDED,
- PROP_SHOW_FALLBACK,
- PROP_SHOW_OTHER,
- PROP_SHOW_ALL,
- PROP_DEFAULT_TEXT,
- N_PROPERTIES
-};
-
-enum {
- SIGNAL_APPLICATION_SELECTED,
- SIGNAL_APPLICATION_ACTIVATED,
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS] = { 0, };
-
-static void gtk_open_with_widget_iface_init (GtkOpenWithIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GtkOpenWithWidget, gtk_open_with_widget, GTK_TYPE_BOX,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_OPEN_WITH,
- gtk_open_with_widget_iface_init));
-
-static void
-refresh_and_emit_app_selected (GtkOpenWithWidget *self,
- GtkTreeSelection *selection)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- GAppInfo *info = NULL;
- gboolean should_emit = FALSE;
-
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- gtk_tree_model_get (model, &iter,
- COLUMN_APP_INFO, &info,
- -1);
- }
-
- if (info == NULL)
- return;
-
- if (self->priv->selected_app_info != NULL)
- {
- if (!g_app_info_equal (self->priv->selected_app_info, info))
- {
- should_emit = TRUE;
- g_object_unref (self->priv->selected_app_info);
-
- self->priv->selected_app_info = info;
- }
- }
- else
- {
- should_emit = TRUE;
- self->priv->selected_app_info = info;
- }
-
- if (should_emit)
- g_signal_emit (self, signals[SIGNAL_APPLICATION_SELECTED], 0,
- self->priv->selected_app_info);
-}
-
-static gboolean
-path_is_heading (GtkTreeView *view,
- GtkTreePath *path)
-{
- GtkTreeIter iter;
- GtkTreeModel *model;
- gboolean res;
-
- model = gtk_tree_view_get_model (view);
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter,
- COLUMN_HEADING, &res,
- -1);
-
- return res;
-}
-
-static void
-program_list_selection_activated (GtkTreeView *view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- gpointer user_data)
-{
- GtkOpenWithWidget *self = user_data;
- GtkTreeSelection *selection;
-
- if (path_is_heading (view, path))
- return;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
-
- refresh_and_emit_app_selected (self, selection);
-
- g_signal_emit (self, signals[SIGNAL_APPLICATION_ACTIVATED], 0,
- self->priv->selected_app_info);
-}
-
-static gboolean
-gtk_open_with_search_equal_func (GtkTreeModel *model,
- int column,
- const char *key,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- char *normalized_key;
- char *name, *normalized_name;
- char *path, *normalized_path;
- char *basename, *normalized_basename;
- gboolean ret;
-
- if (key != NULL)
- {
- normalized_key = g_utf8_casefold (key, -1);
- g_assert (normalized_key != NULL);
-
- ret = TRUE;
-
- gtk_tree_model_get (model, iter,
- COLUMN_NAME, &name,
- COLUMN_EXEC, &path,
- -1);
-
- if (name != NULL)
- {
- normalized_name = g_utf8_casefold (name, -1);
- g_assert (normalized_name != NULL);
-
- if (strncmp (normalized_name, normalized_key, strlen (normalized_key)) == 0) {
- ret = FALSE;
- }
-
- g_free (normalized_name);
- }
-
- if (ret && path != NULL)
- {
- normalized_path = g_utf8_casefold (path, -1);
- g_assert (normalized_path != NULL);
-
- basename = g_path_get_basename (path);
- g_assert (basename != NULL);
-
- normalized_basename = g_utf8_casefold (basename, -1);
- g_assert (normalized_basename != NULL);
-
- if (strncmp (normalized_path, normalized_key, strlen (normalized_key)) == 0 ||
- strncmp (normalized_basename, normalized_key, strlen (normalized_key)) == 0) {
- ret = FALSE;
- }
-
- g_free (basename);
- g_free (normalized_basename);
- g_free (normalized_path);
- }
-
- g_free (name);
- g_free (path);
- g_free (normalized_key);
-
- return ret;
- }
- else
- {
- return TRUE;
- }
-}
-
-static gint
-gtk_open_with_sort_func (GtkTreeModel *model,
- GtkTreeIter *a,
- GtkTreeIter *b,
- gpointer user_data)
-{
- gboolean a_recommended, b_recommended;
- gboolean a_fallback, b_fallback;
- gboolean a_heading, b_heading;
- gboolean a_default, b_default;
- gchar *a_name, *b_name, *a_casefold, *b_casefold;
- gint retval = 0;
-
- /* this returns:
- * - <0 if a should show before b
- * - =0 if a is the same as b
- * - >0 if a should show after b
- */
-
- gtk_tree_model_get (model, a,
- COLUMN_NAME, &a_name,
- COLUMN_RECOMMENDED, &a_recommended,
- COLUMN_FALLBACK, &a_fallback,
- COLUMN_HEADING, &a_heading,
- COLUMN_DEFAULT, &a_default,
- -1);
-
- gtk_tree_model_get (model, b,
- COLUMN_NAME, &b_name,
- COLUMN_RECOMMENDED, &b_recommended,
- COLUMN_FALLBACK, &b_fallback,
- COLUMN_HEADING, &b_heading,
- COLUMN_DEFAULT, &b_default,
- -1);
-
- /* the default one always wins */
- if (a_default && !b_default)
- {
- retval = -1;
- goto out;
- }
-
- if (b_default && !a_default)
- {
- retval = 1;
- goto out;
- }
-
- /* the recommended one always wins */
- if (a_recommended && !b_recommended)
- {
- retval = -1;
- goto out;
- }
-
- if (b_recommended && !a_recommended)
- {
- retval = 1;
- goto out;
- }
-
- /* the recommended one always wins */
- if (a_fallback && !b_fallback)
- {
- retval = -1;
- goto out;
- }
-
- if (b_fallback && !a_fallback)
- {
- retval = 1;
- goto out;
- }
-
- /* they're both recommended/falback or not, so if one is a heading, wins */
- if (a_heading)
- {
- return -1;
- goto out;
- }
-
- if (b_heading)
- {
- return 1;
- goto out;
- }
-
- /* don't order by name recommended applications, but use GLib's ordering */
- if (!a_recommended)
- {
- a_casefold = a_name != NULL ?
- g_utf8_casefold (a_name, -1) : NULL;
- b_casefold = b_name != NULL ?
- g_utf8_casefold (b_name, -1) : NULL;
-
- retval = g_strcmp0 (a_casefold, b_casefold);
-
- g_free (a_casefold);
- g_free (b_casefold);
- }
-
- out:
- g_free (a_name);
- g_free (b_name);
-
- return retval;
-}
-
-static void
-padding_cell_renderer_func (GtkTreeViewColumn *column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- gboolean heading;
-
- gtk_tree_model_get (model, iter,
- COLUMN_HEADING, &heading,
- -1);
- if (heading)
- g_object_set (cell,
- "visible", FALSE,
- "xpad", 0,
- "ypad", 0,
- NULL);
- else
- g_object_set (cell,
- "visible", TRUE,
- "xpad", 3,
- "ypad", 3,
- NULL);
-}
-
-static gboolean
-gtk_open_with_selection_func (GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_currently_selected,
- gpointer user_data)
-{
- GtkTreeIter iter;
- gboolean heading;
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter,
- COLUMN_HEADING, &heading,
- -1);
-
- return !heading;
-}
-
-static gint
-compare_apps_func (gconstpointer a,
- gconstpointer b)
-{
- return !g_app_info_equal (G_APP_INFO (a), G_APP_INFO (b));
-}
-
-static gboolean
-gtk_open_with_widget_add_section (GtkOpenWithWidget *self,
- const gchar *heading_title,
- gboolean show_headings,
- gboolean recommended,
- gboolean fallback,
- GList *applications,
- GList *exclude_apps)
-{
- gboolean heading_added, unref_icon;
- GtkTreeIter iter;
- GAppInfo *app;
- gchar *app_string, *bold_string;
- GIcon *icon;
- GList *l;
- gboolean retval;
-
- retval = FALSE;
- heading_added = FALSE;
- bold_string = g_strdup_printf ("<b>%s</b>", heading_title);
-
- for (l = applications; l != NULL; l = l->next)
- {
- app = l->data;
-
- if (exclude_apps != NULL &&
- g_list_find_custom (exclude_apps, app,
- (GCompareFunc) compare_apps_func))
- continue;
-
- if (!heading_added && show_headings)
- {
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_HEADING_TEXT, bold_string,
- COLUMN_HEADING, TRUE,
- COLUMN_RECOMMENDED, recommended,
- COLUMN_FALLBACK, fallback,
- -1);
-
- heading_added = TRUE;
- }
-
- app_string = g_strdup_printf ("<b>%s</b>\n%s",
- g_app_info_get_display_name (app) != NULL ?
- g_app_info_get_display_name (app) : "",
- g_app_info_get_description (app) != NULL ?
- g_app_info_get_description (app) : "");
-
- icon = g_app_info_get_icon (app);
- if (icon == NULL)
- {
- icon = g_themed_icon_new ("application-x-executable");
- unref_icon = TRUE;
- }
-
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_APP_INFO, app,
- COLUMN_GICON, icon,
- COLUMN_NAME, g_app_info_get_display_name (app),
- COLUMN_DESC, app_string,
- COLUMN_EXEC, g_app_info_get_executable (app),
- COLUMN_HEADING, FALSE,
- COLUMN_RECOMMENDED, recommended,
- COLUMN_FALLBACK, fallback,
- -1);
-
- retval = TRUE;
-
- g_free (app_string);
- if (unref_icon)
- g_object_unref (icon);
-
- unref_icon = FALSE;
- }
-
- g_free (bold_string);
-
- return retval;
-}
-
-
-static void
-gtk_open_with_add_default (GtkOpenWithWidget *self,
- GAppInfo *app)
-{
- GtkTreeIter iter;
- GIcon *icon;
- gchar *string;
- gboolean unref_icon;
-
- unref_icon = FALSE;
- string = g_strdup_printf ("<b>%s</b>", _("Default Application"));
-
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_HEADING_TEXT, string,
- COLUMN_HEADING, TRUE,
- COLUMN_DEFAULT, TRUE,
- -1);
-
- g_free (string);
-
- string = g_strdup_printf ("<b>%s</b>\n%s",
- g_app_info_get_display_name (app) != NULL ?
- g_app_info_get_display_name (app) : "",
- g_app_info_get_description (app) != NULL ?
- g_app_info_get_description (app) : "");
-
- icon = g_app_info_get_icon (app);
- if (icon == NULL)
- {
- icon = g_themed_icon_new ("application-x-executable");
- unref_icon = TRUE;
- }
-
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_APP_INFO, app,
- COLUMN_GICON, icon,
- COLUMN_NAME, g_app_info_get_display_name (app),
- COLUMN_DESC, string,
- COLUMN_EXEC, g_app_info_get_executable (app),
- COLUMN_HEADING, FALSE,
- COLUMN_DEFAULT, TRUE,
- -1);
-
- g_free (string);
-
- if (unref_icon)
- g_object_unref (icon);
-}
-
-static void
-add_no_applications_label (GtkOpenWithWidget *self)
-{
- gchar *text = NULL, *desc;
- const gchar *string;
- GtkTreeIter iter;
-
- if (self->priv->default_text == NULL)
- {
- desc = g_content_type_get_description (self->priv->content_type);
- string = text = g_strdup_printf (_("No applications available to open \"%s\""),
- desc);
- g_free (desc);
- }
- else
- {
- string = self->priv->default_text;
- }
-
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_HEADING_TEXT, string,
- COLUMN_HEADING, TRUE,
- -1);
-
- g_free (text);
-}
-
-static void
-gtk_open_with_widget_select_first (GtkOpenWithWidget *self)
-{
- GtkTreeIter iter;
- GAppInfo *info = NULL;
- GtkTreeModel *model;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->program_list));
- gtk_tree_model_get_iter_first (model, &iter);
-
- while (info == NULL)
- {
- gtk_tree_model_get (model, &iter,
- COLUMN_APP_INFO, &info,
- -1);
-
- if (info != NULL)
- break;
-
- if (!gtk_tree_model_iter_next (model, &iter))
- break;
- }
-
- if (info != NULL)
- {
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
- gtk_tree_selection_select_iter (selection, &iter);
-
- g_object_unref (info);
- }
-}
-
-static void
-gtk_open_with_widget_real_add_items (GtkOpenWithWidget *self)
-{
- GList *all_applications = NULL, *recommended_apps = NULL, *fallback_apps = NULL;
- GList *exclude_apps = NULL;
- GAppInfo *default_app = NULL;
- gboolean show_headings;
- gboolean apps_added;
-
- show_headings = TRUE;
- apps_added = FALSE;
-
- if (self->priv->show_all)
- show_headings = FALSE;
-
- if (self->priv->show_default)
- {
- default_app = g_app_info_get_default_for_type (self->priv->content_type, FALSE);
-
- if (default_app != NULL)
- {
- gtk_open_with_add_default (self, default_app);
- apps_added = TRUE;
- exclude_apps = g_list_prepend (exclude_apps, default_app);
- }
- }
-
- if (self->priv->show_recommended || self->priv->show_all)
- {
- recommended_apps = g_app_info_get_recommended_for_type (self->priv->content_type);
-
- apps_added |= gtk_open_with_widget_add_section (self, _("Recommended Applications"),
- show_headings,
- !self->priv->show_all, /* mark as recommended */
- FALSE, /* mark as fallback */
- recommended_apps, exclude_apps);
-
- exclude_apps = g_list_concat (exclude_apps,
- g_list_copy (recommended_apps));
- }
-
- if (self->priv->show_fallback || self->priv->show_all)
- {
- fallback_apps = g_app_info_get_fallback_for_type (self->priv->content_type);
-
- apps_added |= gtk_open_with_widget_add_section (self, _("Related Applications"),
- show_headings,
- FALSE, /* mark as recommended */
- !self->priv->show_all, /* mark as fallback */
- fallback_apps, exclude_apps);
- exclude_apps = g_list_concat (exclude_apps,
- g_list_copy (fallback_apps));
- }
-
- if (self->priv->show_other || self->priv->show_all)
- {
- all_applications = g_app_info_get_all ();
-
- apps_added |= gtk_open_with_widget_add_section (self, _("Other Applications"),
- show_headings,
- FALSE,
- FALSE,
- all_applications, exclude_apps);
- }
-
- if (!apps_added)
- add_no_applications_label (self);
-
- gtk_open_with_widget_select_first (self);
-
- if (default_app != NULL)
- g_object_unref (default_app);
-
- if (all_applications != NULL)
- g_list_free_full (all_applications, g_object_unref);
-
- if (recommended_apps != NULL)
- g_list_free_full (recommended_apps, g_object_unref);
-
- if (fallback_apps != NULL)
- g_list_free_full (fallback_apps, g_object_unref);
-
- if (exclude_apps != NULL)
- g_list_free (exclude_apps);
-}
-
-static void
-gtk_open_with_widget_add_items (GtkOpenWithWidget *self)
-{
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
- GtkTreeModel *sort;
-
- /* create list store */
- self->priv->program_list_store = gtk_list_store_new (NUM_COLUMNS,
- G_TYPE_APP_INFO,
- G_TYPE_ICON,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN);
- sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->priv->program_list_store));
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (self->priv->program_list),
- GTK_TREE_MODEL (sort));
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort),
- COLUMN_NAME,
- GTK_SORT_ASCENDING);
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort),
- COLUMN_NAME,
- gtk_open_with_sort_func,
- self, NULL);
- gtk_tree_view_set_search_column (GTK_TREE_VIEW (self->priv->program_list),
- COLUMN_NAME);
- gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->priv->program_list),
- gtk_open_with_search_equal_func,
- NULL, NULL);
-
- column = gtk_tree_view_column_new ();
-
- /* initial padding */
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- g_object_set (renderer,
- "xpad", self->priv->show_all ? 0 : 6,
- NULL);
- self->priv->padding_renderer = renderer;
-
- /* heading text renderer */
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "markup", COLUMN_HEADING_TEXT,
- "visible", COLUMN_HEADING,
- NULL);
- g_object_set (renderer,
- "ypad", 6,
- "xpad", 0,
- "wrap-width", 350,
- "wrap-mode", PANGO_WRAP_WORD,
- NULL);
-
- /* padding renderer for non-heading cells */
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_cell_data_func (column, renderer,
- padding_cell_renderer_func,
- NULL, NULL);
-
- /* app icon renderer */
- renderer = gtk_cell_renderer_pixbuf_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "gicon", COLUMN_GICON,
- NULL);
- g_object_set (renderer,
- "stock-size", GTK_ICON_SIZE_DIALOG,
- NULL);
-
- /* app name renderer */
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, TRUE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "markup", COLUMN_DESC,
- NULL);
- g_object_set (renderer,
- "ellipsize", PANGO_ELLIPSIZE_END,
- "ellipsize-set", TRUE,
- NULL);
-
- gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
- gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->program_list), column);
-
- /* populate the widget */
- gtk_open_with_widget_real_add_items (self);
-}
-
-static void
-gtk_open_with_widget_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
-
- switch (property_id)
- {
- case PROP_CONTENT_TYPE:
- self->priv->content_type = g_value_dup_string (value);
- break;
- case PROP_SHOW_DEFAULT:
- gtk_open_with_widget_set_show_default (self, g_value_get_boolean (value));
- break;
- case PROP_SHOW_RECOMMENDED:
- gtk_open_with_widget_set_show_recommended (self, g_value_get_boolean (value));
- break;
- case PROP_SHOW_FALLBACK:
- gtk_open_with_widget_set_show_fallback (self, g_value_get_boolean (value));
- break;
- case PROP_SHOW_OTHER:
- gtk_open_with_widget_set_show_other (self, g_value_get_boolean (value));
- break;
- case PROP_SHOW_ALL:
- gtk_open_with_widget_set_show_all (self, g_value_get_boolean (value));
- break;
- case PROP_DEFAULT_TEXT:
- gtk_open_with_widget_set_default_text (self, g_value_get_string (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-gtk_open_with_widget_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
-
- switch (property_id)
- {
- case PROP_CONTENT_TYPE:
- g_value_set_string (value, self->priv->content_type);
- break;
- case PROP_SHOW_DEFAULT:
- g_value_set_boolean (value, self->priv->show_default);
- break;
- case PROP_SHOW_RECOMMENDED:
- g_value_set_boolean (value, self->priv->show_recommended);
- break;
- case PROP_SHOW_FALLBACK:
- g_value_set_boolean (value, self->priv->show_fallback);
- break;
- case PROP_SHOW_OTHER:
- g_value_set_boolean (value, self->priv->show_other);
- break;
- case PROP_SHOW_ALL:
- g_value_set_boolean (value, self->priv->show_all);
- break;
- case PROP_DEFAULT_TEXT:
- g_value_set_string (value, self->priv->default_text);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-gtk_open_with_widget_constructed (GObject *object)
-{
- GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
-
- g_assert (self->priv->content_type != NULL);
-
- if (G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->constructed != NULL)
- G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->constructed (object);
-
- gtk_open_with_widget_add_items (self);
-}
-
-static void
-gtk_open_with_widget_finalize (GObject *object)
-{
- GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
-
- g_free (self->priv->content_type);
- g_free (self->priv->default_text);
-
- G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->finalize (object);
-}
-
-static void
-gtk_open_with_widget_dispose (GObject *object)
-{
- GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
-
- if (self->priv->selected_app_info != NULL)
- {
- g_object_unref (self->priv->selected_app_info);
- self->priv->selected_app_info = NULL;
- }
-
- G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->dispose (object);
-}
-
-static void
-gtk_open_with_widget_class_init (GtkOpenWithWidgetClass *klass)
-{
- GObjectClass *gobject_class;
- GParamSpec *pspec;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->dispose = gtk_open_with_widget_dispose;
- gobject_class->finalize = gtk_open_with_widget_finalize;
- gobject_class->set_property = gtk_open_with_widget_set_property;
- gobject_class->get_property = gtk_open_with_widget_get_property;
- gobject_class->constructed = gtk_open_with_widget_constructed;
-
- g_object_class_override_property (gobject_class, PROP_CONTENT_TYPE, "content-type");
-
- pspec = g_param_spec_boolean ("show-default",
- P_("Show default app"),
- P_("Whether the widget should show the default application"),
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (gobject_class, PROP_SHOW_DEFAULT, pspec);
-
- pspec = g_param_spec_boolean ("show-recommended",
- P_("Show recommended apps"),
- P_("Whether the widget should show recommended applications"),
- TRUE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (gobject_class, PROP_SHOW_RECOMMENDED, pspec);
-
- pspec = g_param_spec_boolean ("show-fallback",
- P_("Show fallback apps"),
- P_("Whether the widget should show fallback applications"),
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (gobject_class, PROP_SHOW_FALLBACK, pspec);
-
- pspec = g_param_spec_boolean ("show-other",
- P_("Show other apps"),
- P_("Whether the widget should show other applications"),
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (gobject_class, PROP_SHOW_OTHER, pspec);
-
- pspec = g_param_spec_boolean ("show-all",
- P_("Show all apps"),
- P_("Whether the widget should show all applications"),
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (gobject_class, PROP_SHOW_ALL, pspec);
-
- pspec = g_param_spec_string ("default-text",
- P_("Widget's default text"),
- P_("The default text appearing when there are no applications"),
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (gobject_class, PROP_DEFAULT_TEXT, pspec);
-
- signals[SIGNAL_APPLICATION_SELECTED] =
- g_signal_new ("application-selected",
- GTK_TYPE_OPEN_WITH_WIDGET,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GtkOpenWithWidgetClass, application_selected),
- NULL, NULL,
- _gtk_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, G_TYPE_APP_INFO);
-
- signals[SIGNAL_APPLICATION_ACTIVATED] =
- g_signal_new ("application-activated",
- GTK_TYPE_OPEN_WITH_WIDGET,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GtkOpenWithWidgetClass, application_activated),
- NULL, NULL,
- _gtk_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, G_TYPE_APP_INFO);
-
- g_type_class_add_private (klass, sizeof (GtkOpenWithWidgetPrivate));
-}
-
-static void
-gtk_open_with_widget_init (GtkOpenWithWidget *self)
-{
- GtkWidget *scrolled_window;
- GtkTreeSelection *selection;
-
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_OPEN_WITH_WIDGET,
- GtkOpenWithWidgetPrivate);
- gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
-
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_widget_set_size_request (scrolled_window, 400, 300);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
- gtk_widget_show (scrolled_window);
-
- self->priv->program_list = gtk_tree_view_new ();
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->priv->program_list),
- FALSE);
- gtk_container_add (GTK_CONTAINER (scrolled_window), self->priv->program_list);
- gtk_box_pack_start (GTK_BOX (self), scrolled_window, TRUE, TRUE, 0);
- gtk_widget_show (self->priv->program_list);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- gtk_tree_selection_set_select_function (selection, gtk_open_with_selection_func,
- self, NULL);
- g_signal_connect_swapped (selection, "changed",
- G_CALLBACK (refresh_and_emit_app_selected),
- self);
- g_signal_connect (self->priv->program_list, "row-activated",
- G_CALLBACK (program_list_selection_activated),
- self);
-}
-
-static GAppInfo *
-gtk_open_with_widget_get_app_info (GtkOpenWith *object)
-{
- GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
-
- if (self->priv->selected_app_info == NULL)
- return NULL;
-
- return g_object_ref (self->priv->selected_app_info);
-}
-
-static void
-gtk_open_with_widget_refresh (GtkOpenWith *object)
-{
- GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
-
- if (self->priv->program_list_store != NULL)
- {
- gtk_list_store_clear (self->priv->program_list_store);
-
- /* don't add additional xpad if we don't have headings */
- g_object_set (self->priv->padding_renderer,
- "visible", !self->priv->show_all,
- NULL);
-
- gtk_open_with_widget_real_add_items (self);
- }
-}
-
-static void
-gtk_open_with_widget_iface_init (GtkOpenWithIface *iface)
-{
- iface->get_app_info = gtk_open_with_widget_get_app_info;
- iface->refresh = gtk_open_with_widget_refresh;
-}
-
-GtkWidget *
-gtk_open_with_widget_new (const gchar *content_type)
-{
- return g_object_new (GTK_TYPE_OPEN_WITH_WIDGET,
- "content-type", content_type,
- NULL);
-}
-
-void
-gtk_open_with_widget_set_show_default (GtkOpenWithWidget *self,
- gboolean setting)
-{
- g_return_if_fail (GTK_IS_OPEN_WITH_WIDGET (self));
-
- if (self->priv->show_default != setting)
- {
- self->priv->show_default = setting;
-
- g_object_notify (G_OBJECT (self), "show-default");
-
- gtk_open_with_refresh (GTK_OPEN_WITH (self));
- }
-}
-
-gboolean
-gtk_open_with_widget_get_show_default (GtkOpenWithWidget *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_WIDGET (self), FALSE);
-
- return self->priv->show_default;
-}
-
-void
-gtk_open_with_widget_set_show_recommended (GtkOpenWithWidget *self,
- gboolean setting)
-{
- g_return_if_fail (GTK_IS_OPEN_WITH_WIDGET (self));
-
- if (self->priv->show_recommended != setting)
- {
- self->priv->show_recommended = setting;
-
- g_object_notify (G_OBJECT (self), "show-recommended");
-
- gtk_open_with_refresh (GTK_OPEN_WITH (self));
- }
-}
-
-gboolean
-gtk_open_with_widget_get_show_recommended (GtkOpenWithWidget *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_WIDGET (self), FALSE);
-
- return self->priv->show_recommended;
-}
-
-void
-gtk_open_with_widget_set_show_fallback (GtkOpenWithWidget *self,
- gboolean setting)
-{
- g_return_if_fail (GTK_IS_OPEN_WITH_WIDGET (self));
-
- if (self->priv->show_fallback != setting)
- {
- self->priv->show_fallback = setting;
-
- g_object_notify (G_OBJECT (self), "show-fallback");
-
- gtk_open_with_refresh (GTK_OPEN_WITH (self));
- }
-}
-
-gboolean
-gtk_open_with_widget_get_show_fallback (GtkOpenWithWidget *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_WIDGET (self), FALSE);
-
- return self->priv->show_fallback;
-}
-
-void
-gtk_open_with_widget_set_show_other (GtkOpenWithWidget *self,
- gboolean setting)
-{
- g_return_if_fail (GTK_IS_OPEN_WITH_WIDGET (self));
-
- if (self->priv->show_other != setting)
- {
- self->priv->show_other = setting;
-
- g_object_notify (G_OBJECT (self), "show-other");
-
- gtk_open_with_refresh (GTK_OPEN_WITH (self));
- }
-}
-
-gboolean gtk_open_with_widget_get_show_other (GtkOpenWithWidget *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_WIDGET (self), FALSE);
-
- return self->priv->show_other;
-}
-
-void
-gtk_open_with_widget_set_show_all (GtkOpenWithWidget *self,
- gboolean setting)
-{
- g_return_if_fail (GTK_IS_OPEN_WITH_WIDGET (self));
-
- if (self->priv->show_all != setting)
- {
- self->priv->show_all = setting;
-
- g_object_notify (G_OBJECT (self), "show-all");
-
- gtk_open_with_refresh (GTK_OPEN_WITH (self));
- }
-}
-
-gboolean
-gtk_open_with_widget_get_show_all (GtkOpenWithWidget *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_WIDGET (self), FALSE);
-
- return self->priv->show_all;
-}
-
-void
-gtk_open_with_widget_set_default_text (GtkOpenWithWidget *self,
- const gchar *text)
-{
- g_return_if_fail (GTK_IS_OPEN_WITH_WIDGET (self));
-
- if (g_strcmp0 (text, self->priv->default_text) != 0)
- {
- g_free (self->priv->default_text);
- self->priv->default_text = g_strdup (text);
-
- g_object_notify (G_OBJECT (self), "default-text");
-
- gtk_open_with_refresh (GTK_OPEN_WITH (self));
- }
-}
-
-const gchar *
-gtk_open_with_widget_get_default_text (GtkOpenWithWidget *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_WIDGET (self), NULL);
-
- return self->priv->default_text;
-}
+++ /dev/null
-/*
- * gtkopenwithwidget.h: an open-with widget
- *
- * Copyright (C) 2004 Novell, Inc.
- * Copyright (C) 2007, 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Dave Camp <dave@novell.com>
- * Alexander Larsson <alexl@redhat.com>
- * Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#ifndef __GTK_OPEN_WITH_WIDGET_H__
-#define __GTK_OPEN_WITH_WIDGET_H__
-
-#include <gtk/gtkbox.h>
-#include <gio/gio.h>
-
-#define GTK_TYPE_OPEN_WITH_WIDGET\
- (gtk_open_with_widget_get_type ())
-#define GTK_OPEN_WITH_WIDGET(obj)\
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_OPEN_WITH_WIDGET, GtkOpenWithWidget))
-#define GTK_OPEN_WITH_WIDGET_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_OPEN_WITH_WIDGET, GtkOpenWithWidgetClass))
-#define GTK_IS_OPEN_WITH_WIDGET(obj)\
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_OPEN_WITH_WIDGET))
-#define GTK_IS_OPEN_WITH_WIDGET_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_OPEN_WITH_WIDGET))
-#define GTK_OPEN_WITH_WIDGET_GET_CLASS(obj)\
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_OPEN_WITH_WIDGET, GtkOpenWithWidgetClass))
-
-typedef struct _GtkOpenWithWidget GtkOpenWithWidget;
-typedef struct _GtkOpenWithWidgetClass GtkOpenWithWidgetClass;
-typedef struct _GtkOpenWithWidgetPrivate GtkOpenWithWidgetPrivate;
-
-struct _GtkOpenWithWidget {
- GtkBox parent;
-
- /*< private >*/
- GtkOpenWithWidgetPrivate *priv;
-};
-
-struct _GtkOpenWithWidgetClass {
- GtkBoxClass parent_class;
-
- void (* application_selected) (GtkOpenWithWidget *self,
- GAppInfo *app_info);
-
- void (* application_activated) (GtkOpenWithWidget *self,
- GAppInfo *app_info);
-
- /* padding for future class expansion */
- gpointer padding[16];
-};
-
-typedef enum {
- GTK_OPEN_WITH_WIDGET_SHOW_RECOMMENDED = 1 << 0,
- GTK_OPEN_WITH_WIDGET_SHOW_FALLBACK = 1 << 1,
- GTK_OPEN_WITH_WIDGET_SHOW_OTHER = 1 << 2,
- GTK_OPEN_WITH_WIDGET_SHOW_ALL = 1 << 3,
-} GtkOpenWithWidgetShowFlags;
-
-GType gtk_open_with_widget_get_type (void) G_GNUC_CONST;
-
-GtkWidget * gtk_open_with_widget_new (const gchar *content_type);
-
-void gtk_open_with_widget_set_show_default (GtkOpenWithWidget *self,
- gboolean setting);
-gboolean gtk_open_with_widget_get_show_default (GtkOpenWithWidget *self);
-
-void gtk_open_with_widget_set_show_recommended (GtkOpenWithWidget *self,
- gboolean setting);
-gboolean gtk_open_with_widget_get_show_recommended (GtkOpenWithWidget *self);
-
-void gtk_open_with_widget_set_show_fallback (GtkOpenWithWidget *self,
- gboolean setting);
-gboolean gtk_open_with_widget_get_show_fallback (GtkOpenWithWidget *self);
-
-void gtk_open_with_widget_set_show_other (GtkOpenWithWidget *self,
- gboolean setting);
-gboolean gtk_open_with_widget_get_show_other (GtkOpenWithWidget *self);
-
-void gtk_open_with_widget_set_show_all (GtkOpenWithWidget *self,
- gboolean show_all);
-gboolean gtk_open_with_widget_get_show_all (GtkOpenWithWidget *self);
-
-void gtk_open_with_widget_set_default_text (GtkOpenWithWidget *self,
- const gchar *text);
-const gchar * gtk_open_with_widget_get_default_text (GtkOpenWithWidget *self);
-
-#endif /* __GTK_OPEN_WITH_WIDGET_H__ */
testoffscreen \
testoffscreenwindow \
testorientable \
- testopenwith \
+ testappchooser \
testprint \
testrecentchooser \
testrecentchoosermenu \
testnouiprint_DEPENDENCIES = $(TEST_DEPS)
testoffscreen_DEPENDENCIES = $(TEST_DEPS)
testoffscreenwindow_DEPENDENCIES = $(TEST_DEPS)
-testopenwith_DEPENDENCIES = $(TEST_DEPS)
+testappchooser_DEPENDENCIES = $(TEST_DEPS)
testorientable_DEPENDENCIES = $(TEST_DEPS)
testprint_DEPENDENCIES = $(TEST_DEPS)
testrecentchooser_DEPENDENCIES = $(TEST_DEPS)
testnouiprint_LDADD = $(LDADDS)
testoffscreen_LDADD = $(LDADDS)
testoffscreenwindow_LDADD = $(LDADDS)
-testopenwith_LDADD = $(LDADDS)
+testappchooser_LDADD = $(LDADDS)
testorientable_LDADD = $(LDADDS)
testprint_LDADD = $(LDADDS)
testrecentchooser_LDADD = $(LDADDS)
testoffscreenwindow_SOURCES = \
testoffscreenwindow.c
-testopenwith_SOURCES = \
- testopenwith.c
+testappchooser_SOURCES = \
+ testappchooser.c
testwindows_SOURCES = \
testwindows.c
--- /dev/null
+/* testappchooser.c
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Authors: Cosimo Cecchi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <gtk/gtk.h>
+
+static GtkWidget *toplevel;
+static GFile *file;
+static GtkWidget *grid, *file_l, *open;
+static GtkWidget *radio_file, *radio_content, *dialog;
+static GtkWidget *app_chooser_widget;
+static GtkWidget *recommended, *fallback, *other, *all, *radio;
+
+static void
+dialog_response (GtkDialog *d,
+ gint response_id,
+ gpointer user_data)
+{
+ GAppInfo *app_info;
+ const gchar *name;
+
+ g_print ("Response: %d\n", response_id);
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ app_info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (d));
+ name = g_app_info_get_name (app_info);
+ g_print ("Application selected: %s\n", name);
+
+ g_object_unref (app_info);
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (d));
+ dialog = NULL;
+}
+
+static void
+bind_props (void)
+{
+ g_object_bind_property (recommended, "active",
+ app_chooser_widget, "show-recommended",
+ G_BINDING_SYNC_CREATE);
+ g_object_bind_property (fallback, "active",
+ app_chooser_widget, "show-fallback",
+ G_BINDING_SYNC_CREATE);
+ g_object_bind_property (other, "active",
+ app_chooser_widget, "show-other",
+ G_BINDING_SYNC_CREATE);
+ g_object_bind_property (all, "active",
+ app_chooser_widget, "show-all",
+ G_BINDING_SYNC_CREATE);
+ g_object_bind_property (radio, "active",
+ app_chooser_widget, "radio-mode",
+ G_BINDING_SYNC_CREATE);
+}
+
+static void
+prepare_dialog (void)
+{
+ gboolean use_file = FALSE;
+ gchar *content_type = NULL;
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_file)))
+ use_file = TRUE;
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_content)))
+ use_file = FALSE;
+
+ if (use_file)
+ {
+ dialog = gtk_app_chooser_dialog_new (GTK_WINDOW (toplevel),
+ 0, file);
+ }
+ else
+ {
+ GFileInfo *info;
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ 0, NULL, NULL);
+ content_type = g_strdup (g_file_info_get_content_type (info));
+
+ g_object_unref (info);
+
+ dialog = gtk_app_chooser_dialog_new_for_content_type (GTK_WINDOW (toplevel),
+ 0, content_type);
+ }
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (dialog_response), NULL);
+
+ g_free (content_type);
+
+ app_chooser_widget = gtk_app_chooser_dialog_get_widget (GTK_APP_CHOOSER_DIALOG (dialog));
+ bind_props ();
+}
+
+static void
+display_dialog (void)
+{
+ if (dialog == NULL)
+ prepare_dialog ();
+
+ gtk_widget_show (dialog);
+}
+
+static void
+button_clicked (GtkButton *b,
+ gpointer user_data)
+{
+ GtkWidget *w;
+ gchar *path;
+
+ w = gtk_file_chooser_dialog_new ("Select file",
+ GTK_WINDOW (toplevel),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_dialog_run (GTK_DIALOG (w));
+ file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (w));
+ path = g_file_get_path (file);
+ gtk_button_set_label (GTK_BUTTON (file_l), path);
+
+ gtk_widget_destroy (w);
+
+ gtk_widget_set_sensitive (open, TRUE);
+
+ g_free (path);
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GtkWidget *w1;
+ gchar *path;
+
+ g_type_init ();
+ gtk_init (&argc, &argv);
+
+ toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_container_set_border_width (GTK_CONTAINER (toplevel), 12);
+ grid = gtk_grid_new ();
+
+ w1 = gtk_label_new ("File:");
+ gtk_widget_set_halign (w1, GTK_ALIGN_START);
+ gtk_grid_attach (GTK_GRID (grid),
+ w1, 0, 0, 1, 1);
+
+ file_l = gtk_button_new ();
+ path = g_build_filename (g_get_current_dir (), "apple-red.png", NULL);
+ file = g_file_new_for_path (path);
+ gtk_button_set_label (GTK_BUTTON (file_l), path);
+ g_free (path);
+
+ gtk_widget_set_halign (file_l, GTK_ALIGN_START);
+ gtk_grid_attach_next_to (GTK_GRID (grid), file_l,
+ w1, GTK_POS_RIGHT, 1, 1);
+ g_signal_connect (file_l, "clicked",
+ G_CALLBACK (button_clicked), NULL);
+
+ radio_file = gtk_radio_button_new_with_label (NULL, "Use GFile");
+ radio_content = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_file),
+ "Use content type");
+
+ gtk_grid_attach (GTK_GRID (grid), radio_file,
+ 0, 1, 1, 1);
+ gtk_grid_attach_next_to (GTK_GRID (grid), radio_content,
+ radio_file, GTK_POS_BOTTOM, 1, 1);
+
+ open = gtk_button_new_with_label ("Trigger App Chooser dialog");
+ gtk_grid_attach_next_to (GTK_GRID (grid), open,
+ radio_content, GTK_POS_BOTTOM, 1, 1);
+
+ recommended = gtk_check_button_new_with_label ("Show recommended");
+ gtk_grid_attach_next_to (GTK_GRID (grid), recommended,
+ open, GTK_POS_BOTTOM, 1, 1);
+ g_object_set (recommended, "active", TRUE, NULL);
+
+ fallback = gtk_check_button_new_with_label ("Show fallback");
+ gtk_grid_attach_next_to (GTK_GRID (grid), fallback,
+ recommended, GTK_POS_RIGHT, 1, 1);
+
+ other = gtk_check_button_new_with_label ("Show other");
+ gtk_grid_attach_next_to (GTK_GRID (grid), other,
+ fallback, GTK_POS_RIGHT, 1, 1);
+
+ all = gtk_check_button_new_with_label ("Show all");
+ gtk_grid_attach_next_to (GTK_GRID (grid), all,
+ other, GTK_POS_RIGHT, 1, 1);
+
+ radio = gtk_check_button_new_with_label ("Radio mode");
+ gtk_grid_attach_next_to (GTK_GRID (grid), radio,
+ all, GTK_POS_BOTTOM, 1, 1);
+
+ prepare_dialog ();
+ g_signal_connect (open, "clicked",
+ G_CALLBACK (display_dialog), NULL);
+
+ gtk_container_add (GTK_CONTAINER (toplevel), grid);
+
+ gtk_widget_show_all (toplevel);
+ g_signal_connect (toplevel, "delete-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ gtk_main ();
+
+ return EXIT_SUCCESS;
+}
+++ /dev/null
-/* testopenwith.c
- * Copyright (C) 2010 Red Hat, Inc.
- * Authors: Cosimo Cecchi
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <gtk/gtk.h>
-
-static GtkWidget *toplevel;
-static GFile *file;
-static GtkWidget *grid, *file_l, *open;
-static GtkWidget *radio_file, *radio_content, *dialog;
-static GtkWidget *open_with_widget;
-static GtkWidget *recommended, *fallback, *other, *all, *radio;
-
-static void
-dialog_response (GtkDialog *d,
- gint response_id,
- gpointer user_data)
-{
- GAppInfo *app_info;
- const gchar *name;
-
- g_print ("Response: %d\n", response_id);
-
- if (response_id == GTK_RESPONSE_OK)
- {
- app_info = gtk_open_with_get_app_info (GTK_OPEN_WITH (d));
- name = g_app_info_get_name (app_info);
- g_print ("Application selected: %s\n", name);
-
- g_object_unref (app_info);
- }
-
- gtk_widget_destroy (GTK_WIDGET (d));
- dialog = NULL;
-}
-
-static void
-bind_props (void)
-{
- g_object_bind_property (recommended, "active",
- open_with_widget, "show-recommended",
- G_BINDING_SYNC_CREATE);
- g_object_bind_property (fallback, "active",
- open_with_widget, "show-fallback",
- G_BINDING_SYNC_CREATE);
- g_object_bind_property (other, "active",
- open_with_widget, "show-other",
- G_BINDING_SYNC_CREATE);
- g_object_bind_property (all, "active",
- open_with_widget, "show-all",
- G_BINDING_SYNC_CREATE);
- g_object_bind_property (radio, "active",
- open_with_widget, "radio-mode",
- G_BINDING_SYNC_CREATE);
-}
-
-static void
-prepare_dialog (void)
-{
- gboolean use_file = FALSE;
- gchar *content_type = NULL;
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_file)))
- use_file = TRUE;
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_content)))
- use_file = FALSE;
-
- if (use_file)
- {
- dialog = gtk_open_with_dialog_new (GTK_WINDOW (toplevel),
- 0, file);
- }
- else
- {
- GFileInfo *info;
-
- info = g_file_query_info (file,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- 0, NULL, NULL);
- content_type = g_strdup (g_file_info_get_content_type (info));
-
- g_object_unref (info);
-
- dialog = gtk_open_with_dialog_new_for_content_type (GTK_WINDOW (toplevel),
- 0, content_type);
- }
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (dialog_response), NULL);
-
- g_free (content_type);
-
- open_with_widget = gtk_open_with_dialog_get_widget (GTK_OPEN_WITH_DIALOG (dialog));
- bind_props ();
-}
-
-static void
-display_dialog (void)
-{
- if (dialog == NULL)
- prepare_dialog ();
-
- gtk_widget_show (dialog);
-}
-
-static void
-button_clicked (GtkButton *b,
- gpointer user_data)
-{
- GtkWidget *w;
- gchar *path;
-
- w = gtk_file_chooser_dialog_new ("Select file",
- GTK_WINDOW (toplevel),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_dialog_run (GTK_DIALOG (w));
- file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (w));
- path = g_file_get_path (file);
- gtk_button_set_label (GTK_BUTTON (file_l), path);
-
- gtk_widget_destroy (w);
-
- gtk_widget_set_sensitive (open, TRUE);
-
- g_free (path);
-}
-
-int
-main (int argc,
- char **argv)
-{
- GtkWidget *w1;
- gchar *path;
-
- g_type_init ();
- gtk_init (&argc, &argv);
-
- toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_container_set_border_width (GTK_CONTAINER (toplevel), 12);
- grid = gtk_grid_new ();
-
- w1 = gtk_label_new ("File:");
- gtk_widget_set_halign (w1, GTK_ALIGN_START);
- gtk_grid_attach (GTK_GRID (grid),
- w1, 0, 0, 1, 1);
-
- file_l = gtk_button_new ();
- path = g_build_filename (g_get_current_dir (), "apple-red.png", NULL);
- file = g_file_new_for_path (path);
- gtk_button_set_label (GTK_BUTTON (file_l), path);
- g_free (path);
-
- gtk_widget_set_halign (file_l, GTK_ALIGN_START);
- gtk_grid_attach_next_to (GTK_GRID (grid), file_l,
- w1, GTK_POS_RIGHT, 1, 1);
- g_signal_connect (file_l, "clicked",
- G_CALLBACK (button_clicked), NULL);
-
- radio_file = gtk_radio_button_new_with_label (NULL, "Use GFile");
- radio_content = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_file),
- "Use content type");
-
- gtk_grid_attach (GTK_GRID (grid), radio_file,
- 0, 1, 1, 1);
- gtk_grid_attach_next_to (GTK_GRID (grid), radio_content,
- radio_file, GTK_POS_BOTTOM, 1, 1);
-
- open = gtk_button_new_with_label ("Trigger Open With dialog");
- gtk_grid_attach_next_to (GTK_GRID (grid), open,
- radio_content, GTK_POS_BOTTOM, 1, 1);
-
- recommended = gtk_check_button_new_with_label ("Show recommended");
- gtk_grid_attach_next_to (GTK_GRID (grid), recommended,
- open, GTK_POS_BOTTOM, 1, 1);
- g_object_set (recommended, "active", TRUE, NULL);
-
- fallback = gtk_check_button_new_with_label ("Show fallback");
- gtk_grid_attach_next_to (GTK_GRID (grid), fallback,
- recommended, GTK_POS_RIGHT, 1, 1);
-
- other = gtk_check_button_new_with_label ("Show other");
- gtk_grid_attach_next_to (GTK_GRID (grid), other,
- fallback, GTK_POS_RIGHT, 1, 1);
-
- all = gtk_check_button_new_with_label ("Show all");
- gtk_grid_attach_next_to (GTK_GRID (grid), all,
- other, GTK_POS_RIGHT, 1, 1);
-
- radio = gtk_check_button_new_with_label ("Radio mode");
- gtk_grid_attach_next_to (GTK_GRID (grid), radio,
- all, GTK_POS_BOTTOM, 1, 1);
-
- prepare_dialog ();
- g_signal_connect (open, "clicked",
- G_CALLBACK (display_dialog), NULL);
-
- gtk_container_add (GTK_CONTAINER (toplevel), grid);
-
- gtk_widget_show_all (toplevel);
- g_signal_connect (toplevel, "delete-event",
- G_CALLBACK (gtk_main_quit), NULL);
-
- gtk_main ();
-
- return EXIT_SUCCESS;
-}